2016-10-02 20 views
0

在Windows中,当我创建QMainWindow时,我可以通过单击标题栏并拖动它在屏幕上移动它。通过单击内部控件而不是标题栏来移动窗口

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

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

有没有办法做到这一点?

回答

1

你只需要实施必要的鼠标事件通过覆盖MyWidgetmousePressEvent()mouseMoveEvent()mouseReleaseEvent()处理程序处理。

  1. 检测鼠标的时候,请
  2. 虽然移动当前鼠标的位置,获得当前鼠标的位置,计算出差额,保存新的位置,通过diff的

你可以将窗口移动窗口(顶部从MyWidgetwindow()方法。

1

这是一个关于如何实现虚假标题栏的例子,它具有标准按钮(最小化,最大化,关闭),并且可以拖动来移动整个窗口(这是基于@凯文答案中的方法) 。

screenshot

#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" 
相关问题