Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通过单击内部小部件而不是标题栏来移动窗口_C++_Qt_Window_Mousemove_Titlebar - Fatal编程技术网

C++ 通过单击内部小部件而不是标题栏来移动窗口

C++ 通过单击内部小部件而不是标题栏来移动窗口,c++,qt,window,mousemove,titlebar,C++,Qt,Window,Mousemove,Titlebar,在Windows中,当我创建QMainWindow时,我可以通过单击标题栏并拖动它在屏幕上移动它 在我的应用程序中,我通过使用setWindowFlags(Qt::CustomizeWindowint)隐藏了标题栏,我试图使用小部件构建一个自定义标题栏,并使用setMenuWidget(myWidget)在菜单空间中设置它 现在,我想重现最初的行为:我想在QMainWindow中单击我的MyWidget小部件,当按下鼠标时,拖动鼠标移动窗口 有办法吗?您只需要通过覆盖MyWidget的mouse

在Windows中,当我创建QMainWindow时,我可以通过单击标题栏并拖动它在屏幕上移动它

在我的应用程序中,我通过使用
setWindowFlags(Qt::CustomizeWindowint)
隐藏了标题栏,我试图使用小部件构建一个自定义标题栏,并使用
setMenuWidget(myWidget)
在菜单空间中设置它

现在,我想重现最初的行为:我想在QMainWindow中单击我的
MyWidget
小部件,当按下鼠标时,拖动鼠标移动窗口


有办法吗?

您只需要通过覆盖
MyWidget
mousePressEvent()
mouseMoveEvent()
mousereleasevent()
处理程序来实现必要的鼠标事件处理

  • 检测鼠标下降,获取当前鼠标位置
  • 移动时,获取当前鼠标位置,计算差异,保存新位置,按差异移动窗口

  • 您可以通过
    window()
    方法从
    MyWidget
    内部获取窗口(顶级小部件)。

    您只需通过覆盖
    MyWidget
    mousePressEvent()
    mouseMoveEvent()
    mousereleasevent()
    处理程序来实现必要的鼠标事件处理

  • 检测鼠标下降,获取当前鼠标位置
  • 移动时,获取当前鼠标位置,计算差异,保存新位置,按差异移动窗口

  • 您可以通过
    window()
    方法从
    MyWidget
    内部获取窗口(顶级小部件)。

    这是一个关于如何实现假标题栏的示例,该标题栏具有标准按钮(最小化、最大化、关闭),可以拖动以移动整个窗口(这基于@Kevin回答中的方法)

    #包括
    类FakeTitleBar:publicqwidget{
    Q_对象
    公众:
    显式FakeTitleBar(QWidget*parent=nullptr):QWidget(parent){
    label.setSizePolicy(QSizePolicy::Expansing,
    QSizePolicy::扩展);
    layout.addWidget(&label);
    layout.addWidget(&buttonMinimize);
    layout.addWidget(&buttonMaximize);
    layout.addWidget(&buttonClose);
    //将按钮信号连接到插槽
    连接(&Button最小化,&QPushButton::单击,
    这,&FakeTitleBar::MinimizeWindow);
    连接(&buttonMaximize,&QPushButton::单击,
    这,&FakeTitleBar::MaximizeWindow);
    连接(&buttonClose,&QPushButton::单击,
    这是(FakeTitleBar::CloseWindow);
    //设置垂直固定大小策略
    //这样标题栏就不会占用任何额外的空间
    设置策略(QSizePolicy::首选,QSizePolicy::固定);
    //一点造型
    setStyleSheet(“QPushButton{margin:0px;padding:5px;}”
    “QWidget{背景色:蓝色;颜色:白色;}”);
    }
    公众时段:
    //对应按钮的插槽
    void MinimizeWindow(){
    window()->showmimized();
    }
    void MaximizeWindow(){
    如果(!window()->isMaximized())
    window()->showMaximized();
    其他的
    window()->showNormal();
    }
    void CloseWindow(){
    window()->close();
    }
    受保护的:
    作废鼠标压力事件(QMouseEvent*事件){
    //保存按键位置(相对于当前小部件)
    按pos=事件->pos();
    isMoving=真;
    }
    作废mouseMoveEvent(QMouseEvent*事件){
    //isMoving标志确保拖放事件起源于
    //从标题栏中,因为否则窗口不应移动
    如果(正在移动){
    //计算按下位置和新鼠标位置之间的差值
    //(这是相对于当前小部件的)
    QPoint diff=事件->位置()-按位置;
    //通过不同的方式移动窗口
    window()->move(window()->pos()+diff);
    }
    }
    无效mouseReleaseEvent(QMouseEvent*/*event*/){
    //拖放操作结束
    isMoving=假;
    }
    //双击标题栏可以使窗口最大化
    void mouseDoubleClickEvent(QMouseEvent*/*event*/){
    最大化窗口();
    }
    //以便样式表应用于此自定义小部件
    //看https://doc.qt.io/qt-5/stylesheet-reference.html#qwidget-小部件
    无效paintEvent(QPaintEvent*)
    {
    qstyleopt;
    选择初始(本);
    油漆工p(本);
    style()->drawPrimitive(QStyle::PE_小部件,&opt,&p,this);
    }
    私人:
    QHBoxLayout布局{this};
    QLabel标签{“假标题栏”};
    QPushButton按钮最小化{“-”};
    QPushButton按钮最大化{“M”};
    QPushButton按钮关闭{“X”};
    点按位置;
    布尔·伊斯莫温{false};
    };
    //样本使用
    类Widget:publicqwidget{
    公众:
    显式小部件(QWidget*parent=nullptr):QWidget(parent){
    setWindowFlags(Qt::CustomizeWindowint);
    layout.addWidget(标题栏和标题栏);
    layout.addWidget(&label);
    布局.setContentsMargins(0,0,0,0);
    label.setAlignment(Qt::AlignCenter);
    //窗口的默认大小
    调整大小(320240);
    }
    ~Widget(){}
    私人:
    QVBoxLayout布局{this};
    FakeTitleBar标题栏;
    QLabel标签{“这是一个示例窗口”};
    };
    int main(int argc,char*argv[]){
    QApplication应用程序(argc、argv);
    小部件w;
    w、 show();
    返回app.exec();
    }
    #包括“main.moc”
    
    这是一个关于如何实现假标题栏的示例,该标题栏具有标准按钮(最小化、最大化、关闭),可以拖动以移动整个窗口(这是基于@Kevin答案中的方法)

    #包括
    类FakeTitleBar:publicqwidget{
    Q_对象
    公众:
    显式FakeTitleBar(QWidget*parent=nullptr):QWidget(parent){
    标签设置策略(QS)
    
    #include <QtWidgets>
    
    
    class FakeTitleBar : public QWidget{
        Q_OBJECT
    public:
        explicit FakeTitleBar(QWidget* parent= nullptr):QWidget(parent){
            label.setSizePolicy(QSizePolicy::Expanding,
                                QSizePolicy::Expanding);
            layout.addWidget(&label);
            layout.addWidget(&buttonMinimize);
            layout.addWidget(&buttonMaximize);
            layout.addWidget(&buttonClose);
            //connecting buttons' signals to slots
            connect(&buttonMinimize, &QPushButton::clicked,
                    this, &FakeTitleBar::MinimizeWindow);
            connect(&buttonMaximize, &QPushButton::clicked,
                    this, &FakeTitleBar::MaximizeWindow);
            connect(&buttonClose, &QPushButton::clicked,
                    this, &FakeTitleBar::CloseWindow);
            //setting vertical fixed size policy
            //so that the title bar does not take up any additional space
            setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
            //a bit of styling
            setStyleSheet("QPushButton {margin:0px; padding:5px;}"
                          "QWidget {background-color:blue; color:white;}");
        }
    
    public slots:
        //slots for corresponding buttons
        void MinimizeWindow(){
            window()->showMinimized();
        }
        void MaximizeWindow(){
            if(!window()->isMaximized())
                window()->showMaximized();
            else
                window()->showNormal();
        }
        void CloseWindow(){
            window()->close();
        }
    
    protected:
        void mousePressEvent(QMouseEvent* event){
            //save the press position (this is relative to the current widget)
            pressPos= event->pos();
            isMoving= true;
        }
        void mouseMoveEvent(QMouseEvent* event){
            //isMoving flag makes sure that the drag and drop event originated
            //from within the titlebar, because otherwise the window shouldn't be moved
            if(isMoving){
                //calculate difference between the press position and the new Mouse position
                //(this is relative to the current widget)
                QPoint diff= event->pos() - pressPos;
                //move the window by diff
                window()->move(window()->pos()+diff);
            }
        }
        void mouseReleaseEvent(QMouseEvent* /*event*/){
            //drag and drop operation end
            isMoving= false;
        }
        //double-clicking on the title bar should maximize the window
        void mouseDoubleClickEvent(QMouseEvent* /*event*/){
            MaximizeWindow();
        }
        //in order for the style sheet to apply on this custom widget
        //see https://doc.qt.io/qt-5/stylesheet-reference.html#qwidget-widget
        void paintEvent(QPaintEvent *)
        {
            QStyleOption opt;
            opt.init(this);
            QPainter p(this);
            style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
        }
    
    private:
        QHBoxLayout layout{this};
        QLabel label{"Fake Title Bar"};
        QPushButton buttonMinimize{"-"};
        QPushButton buttonMaximize{"M"};
        QPushButton buttonClose{"X"};
        QPoint pressPos;
        bool isMoving{false};
    };
    
    //sample usage
    
    class Widget : public QWidget{
    public:
        explicit Widget(QWidget* parent= nullptr):QWidget(parent){
            setWindowFlags(Qt::CustomizeWindowHint);
            layout.addWidget(&titleBar);
            layout.addWidget(&label);
            layout.setContentsMargins(0, 0, 0, 0);
            label.setAlignment(Qt::AlignCenter);
            //default size for the window
            resize(320,240);
        }
        ~Widget(){}
    
    private:
        QVBoxLayout layout{this};
        FakeTitleBar titleBar;
        QLabel label{"this is a sample window"};
    };
    
    int main(int argc, char* argv[]) {
        QApplication app(argc, argv);
    
        Widget w;
        w.show();
    
        return app.exec();
    }
    
    #include "main.moc"