2016-10-02 25 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" 
相關問題