Qt實戰10.支持最小化和最大化的QDockWidget

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事件就可以啦,面對不同的需求要能夠舉一反三,這是程序員必備的技能。

5 下載

測試代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章