2016-10-02 25 views
0

Windowsでは、QMainWindowを作成するときに、タイトルバーをクリックしてドラッグすることで画面を移動できます。タイトルバーの代わりに内部ウィジェットをクリックしてウィンドウを移動する

setWindowFlags(Qt::CustomizeWindowHint)を使用してタイトルバーを非表示にしました。ウィジェットを使用してカスタムタイトルバーを作成し、メニュースペースにsetMenuWidget(myWidget)と設定しようとしています。

元の動作を再現したい:QMainWindow内の私のMyWidgetウィジェットをクリックし、マウスを押しながらマウスをドラッグしてウィンドウを移動する。

これを行う方法はありますか?

答えて

1

mousePressEvent(),mouseMoveEvent()、およびmouseReleaseEvent()ハンドラを上書きするだけで、必要なマウスイベント処理を実装するだけで済みます。

  1. トップ(ダウンマウスを検出動かしながら現在のマウス位置
  2. を取得し、現在のマウス位置を取得し、その差を計算し、新しい位置を保存し、あなたが窓を得ることができます

をdiffをしてウィンドウを移動します内部のMyWidgetからwindow()メソッドまで)。

1

これは標準的なボタン(最小化、最大化、終了)を持つ偽のタイトルバーを実装する方法の例です。ドラッグしてウィンドウ全体を移動できます(これは@ Kevinの答えのアプローチに基づいています) 。

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" 
関連する問題