1 需求描述
由於項目需要,xx軟件的一些模塊均是以dockwidget的方式進行開發的,這樣便於實現靈活佈局;但是再某些情況下需要全屏展示dockwidget中的內容,遺憾的是QDockWidget除了關閉按鈕,最小化、最大化按鈕都沒提供。
簡單整理下需求:在不影響QDockWidget正常功能情況下,當dockwidget懸浮時,自動出現最小化、最大化按鈕使窗口能夠最小化、最大化顯示。
2 設計思路
首先第一點,QDockWidget繼承QWidget,隱隱感覺還是好辦,應該問題不大,穩定情緒不要慌。
2.1 怎麼動態獲取dockwidget的懸浮狀態?
當然是捕獲事件,經測試當dockwidget懸浮狀態改變時會觸發QEvent::ZOrderChange事件,我們只要捕獲到這個事件就可以了。
2.2 怎麼增加dockwidget的最小、最大化按鈕?
剛剛說了,QDockWidget繼承QWidget,通過setWindowFlags設置窗口的標記應該能滿足需求的。
3 代碼實現
理清思路後,下面開始實現,繼承QDockWidget重寫event函數,如下:
#ifndef CUSTOMDOCKWIDGET_H
#define CUSTOMDOCKWIDGET_H
#include <QDockWidget>
class CustomDockWidget : public QDockWidget
{
Q_OBJECT
public:
explicit CustomDockWidget(QWidget *parent = nullptr);
// QObject interface
public:
bool event(QEvent *event) override;
};
#endif // CUSTOMDOCKWIDGET_H
#include "CustomDockWidget.h"
#include <QEvent>
CustomDockWidget::CustomDockWidget(QWidget *parent) : QDockWidget(parent)
{
}
bool CustomDockWidget::event(QEvent *event)
{
if (QEvent::ZOrderChange == event->type()) {
if (windowFlags() & Qt::WindowMaximizeButtonHint) {
return QDockWidget::event(event);
} else {
QWidget w;
setMaximumSize(w.maximumSize());
setWindowFlags(Qt::Dialog
| Qt::WindowCloseButtonHint
| Qt::WindowMaximizeButtonHint
| Qt::WindowMinimizeButtonHint);
show();
}
}
return QDockWidget::event(event);
}
代碼邏輯很簡單,就不需要解釋什麼了吧,捕獲QEvent::ZOrderChange事件,根據窗口標記判斷dockwidget懸浮狀態,然後做不同處理。
setMaximumSize這裏如果不設置,最大化按鈕會是灰色的,因爲dockwidget懸浮後maximumSize會改變,maximumSize如果不夠大的話窗口就不能最大化。
最後那個show()是有必要的,不然雙擊標題欄後dockwidget會隱藏。
4 總結
通過上述過程便完成了dockwidget的最大化、最小話的功能實現,並且對QDockWidget原有的功能也沒有副作用,效果不錯;但是就這樣了嗎?如果用戶想雙擊標題欄實現全屏效果怎麼辦呢?捕獲NonClientAreaMouseButtonDblClick事件就可以啦,面對不同的需求要能夠舉一反三,這是程序員必備的技能。