zoukankan      html  css  js  c++  java
  • Qt实战10.支持最小化和最大化的QDockWidget

    1 需求描述

    由于项目需要,xx软件的一些模块均是以dockwidget的方式进行开发的,这样便于实现灵活布局;但是在某些情况下需要全屏展示dockwidget中的内容,遗憾的是QDockWidget除了关闭按钮,最小化、最大化按钮都没提供。

    简单整理下需求:在不影响QDockWidget正常功能情况下,当dockwidget悬浮时,自动出现最小化、最大化按钮使窗口能够最小化、最大化显示。

    2 设计思路

    首先第一点,QDockWidget继承QWidget,隐隐感觉还是好办,应该问题不大,稳定情绪不要慌。

    2.1 怎么动态获取dockwidget的悬浮状态?

    当然是捕获事件,经测试当dockwidget悬浮状态改变时会触发QEvent::ZOrderChange事件或topLevelChanged信号,我们只要捕获到这个事件或信号就可以了。

    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 (isFloating()) {
                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会隐藏。


    当然,这里也可以通过信号处理,直接连接topLevelChanged信号:

    connect(this, &QDockWidget::topLevelChanged, [=]() {
          if (isFloating()) {
              QWidget w;
              setMaximumSize(w.maximumSize());
              setWindowFlags(Qt::Dialog
                             | Qt::WindowCloseButtonHint
                             | Qt::WindowMaximizeButtonHint
                             | Qt::WindowMinimizeButtonHint);
              show();
          };
    });
    

    最终的效果都一样,但是重写事件的方式可以实现更复杂的功能,灵活度更高,可以应对更复杂的需求。

    4 总结

    通过上述过程便完成了dockwidget的最大化、最小话的功能实现,并且对QDockWidget原有的功能也没有副作用,效果不错;但是就这样了吗?如果用户想双击标题栏实现全屏效果怎么办呢?捕获NonClientAreaMouseButtonDblClick事件就可以啦,面对不同的需求要能够举一反三,这是程序员必备的技能。

    5 下载

    测试代码

    © 版权声明
    文章版权归作者所有,未经允许请勿转载。【QQ交流:115124903】
    THE END
  • 相关阅读:
    keypress事件
    input输入框(blur,change,focus)
    click点击以后添加新class,删除其余同名class
    强制数组并且匹配Array
    模拟鼠标事件
    简单的form操作
    鼠标滚轮事件(mousewheel、DOMMouseScroll)
    事件委托技术
    从程序员到项目经理:项目经理必须懂一点“章法”
    JavaScript项目优化总结
  • 原文地址:https://www.cnblogs.com/luoxiang/p/14277269.html
Copyright © 2011-2022 走看看