2016-10-02 16 views
0

В Windows, когда я создаю QMainWindow, я могу перемещать его по экрану, щелкнув строку заголовка и перетащив его.Переместите окно, щелкнув внутренний виджет, а не заголовок

В моем приложении я скрыл строку заголовка, используя setWindowFlags(Qt::CustomizeWindowHint), и я пытаюсь создать пользовательскую строку заголовка с помощью виджета и установить его в пространстве меню с помощью setMenuWidget(myWidget).

Теперь я хочу воспроизвести исходное поведение: я хочу щелкнуть по моему виджню MyWidget внутри QMainWindow, и, в то время как мышь нажата, перетаскивание мышью перемещает окно.

Есть ли способ сделать это?

ответ

1

Вам просто нужно реализовать обработку путем переписывания MyWidget «s mousePressEvent(), mouseMoveEvent() и mouseReleaseEvent() обработчиков необходимых мышей события.

  1. обнаружить мышь вниз, получить текущую позицию мыши
  2. во время движения, получить текущее положение мыши, вычислить разницу, сохранить новое положение, окна перемещения по дифф

Вы можете получить окно (сверху виджет уровня) изнутри MyWidget через метод window().

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" 

 Смежные вопросы

  • Нет связанных вопросов^_^