QT6 源,七章对话框与多窗体(16)多文档 MDI 窗体 QMdiArea 篇二:源代码带注释

QT6多文档MDI窗体QMdiArea篇二

(6)本源代码定义于 qmdiarea . h

#ifndef QMDIAREA_H
#define QMDIAREA_H

#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qabstractscrollarea.h>
#if QT_CONFIG(tabwidget)
#include <QtWidgets/qtabwidget.h>
#endif

QT_REQUIRE_CONFIG(mdiarea);

QT_BEGIN_NAMESPACE

class QMdiSubWindow;

class QMdiAreaPrivate;

/*
The QMdiArea widget provides an area in which MDI windows are displayed.

Detailed Description :
QMdiArea函数在本质上类似于MDI窗口的窗口管理器。
例如,它会在自身上绘制它所管理的窗口,并将它们以级联或砖块 tile模式排列。
QMdiArea通常被用作QMainWindow中的中心小部件以创建MDI应用程序,但也可以放置在任意布局中。
以下代码在主窗口中添加了一个区域:
    QMainWindow *mainWindow = new QMainWindow;
    mainWindow->setCentralWidget(mdiArea);

与顶层窗口的窗口管理器不同,
只要当前小部件样式支持相应的标志(Qt::WindowFlags),QMdiArea就支持所有窗口标志。
如果某个特定标志不在样式支持范围内(例如WindowShadeButtonHint),
您仍然可以通过调用showShaded()来给窗口添加阴影效果。

QMdiArea 中的子窗口是 QMdiSubWindow的实例。
它们通过调用 addSubWindow()方法被添加到 MDI区域中。
通常,向该函数传递一个设置为内部控件的 QWidget,但也可以直接传递一个QMdiSubWindow。
该类继承自 QWidget,因此在编程时可以使用与常规顶级窗口相同的 APL。
QMdiSubWindow 还具有特定于 MDI窗口的行为。有关更详细的说明,请参阅 QMdiSubWindow 类描述。

当一个子窗口获得键盘焦点或当调用`setFocus()'时,该子窗口将变为激活状态。
用户通过通常的方式移动焦点来激活窗口。
当活动窗口发生变化时,MDI区域会发出`subWindowActivated()信号,
而`activeSubWindow()函数则返回当前激活的子窗口。

便利函数`subWindowList()'返回一个包含所有子窗口的列表。
这些信息可以用于包含窗口列表的弹出菜单中,例如。

子窗口是根据当前的 WindowOrder 排序的。
这被用于subWindowList()方法以及 activateNextSubWindow()和 activatePrevioussubWindow()方法。
此外,在通过 cascadeSubWindows()和tileSubWindows(方法实现窗口的级联或平铺布局时,也会用到这个属性。

QMdiArea为子窗口提供了两种内置布局策略:cascadeSubWindows()和tileSubWindows()。
两者均为槽函数,可以轻松与菜单项关联。

注意:QMdiArea的默认滚动条属性是 Qt::ScrollBarAlwaysOff。

*/

class Q_WIDGETS_EXPORT QMdiArea : public QAbstractScrollArea
{
    Q_OBJECT

    //此属性持有工作区的背景刷。
    //此属性设置工作区区域的背景刷。默认情况下,它采用灰色,但可以是任何刷(例如,颜色、渐变或像素图)。
    Q_PROPERTY(QBrush background READ background WRITE setBackground)

    //enum WindowOrder { CreationOrder,  StackingOrder, ActivationHistoryOrder };
    //此属性用于指定子窗口列表的排序标准。
    //此属性指定了由subWindowList()返回的子窗口列表的排序标准。默认情况下,它是窗口创建顺序。
    Q_PROPERTY(WindowOrder activationOrder READ activationOrder WRITE setActivationOrder)

    //enum ViewMode { SubWindowView, TabbedView };
    //此属性用于指定子窗口在QMdiArea中显示的方式。默认情况下,使用SubWindowView来显示子窗口。
    Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode)

    //此属性表示在标签视图模式下,标签栏是否设置为文档模式。文档模式默认是禁用的。
    Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)

    //此属性决定在标签页视图模式下,标签栏是否应在每个标签上放置关闭按钮。标签默认情况下不可关闭。
    Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable)

    //此属性表示用户在标签页视图模式下是否可以在标签栏区域内移动标签。标签默认情况下不可移动。
    Q_PROPERTY(bool tabsMovable READ tabsMovable WRITE setTabsMovable)

    //此属性用于设置标签在标签页视图模式下的形状。
    //此属性的可能值是QTabWidget::Rounded(默认)或QTabWidget::Triangular。
    Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)

    //此属性在标签页视图模式下表示标签的位置。
    //enum QTabWidget::TabPosition { North, South, West, East };
    Q_PROPERTY(QTabWidget::TabPosition tabPosition READ tabPosition WRITE setTabPosition)

private:
    Q_DISABLE_COPY(QMdiArea)
    Q_DECLARE_PRIVATE(QMdiArea)
    Q_PRIVATE_SLOT(d_func(), void _q_deactivateAllWindows())
    Q_PRIVATE_SLOT(d_func(), void _q_processWindowStateChanged(Qt::WindowStates, Qt::WindowStates))
    Q_PRIVATE_SLOT(d_func(), void _q_currentTabChanged(int))
    Q_PRIVATE_SLOT(d_func(), void _q_closeTab(int))
    Q_PRIVATE_SLOT(d_func(), void _q_moveTab(int, int))

public:

    //Constructs an empty mdi area. parent is passed to QWidget's constructor.
    QMdiArea(QWidget * parent = nullptr);

    ~QMdiArea();

//   Q_PROPERTY(QBrush         background        //工作区的背景刷,默认情况下,它采用灰色
//              READ           background        WRITE     setBackground)
                QBrush         background() const;
                void        setBackground(const QBrush & background);


    //指定用于排序`subWindowList()、返回的子窗口列表的标准。
    //cascadeSubWindows() 和`tileSubWindows()函数在排列窗口时遵循这一顺序。
    enum WindowOrder {
                 CreationOrder, //窗户按照创建的顺序返回。
                 StackingOrder, //窗口按照堆叠的顺序返回,最上面的窗口在列表中位于最后.
        ActivationHistoryOrder  //窗口会按照激活的顺序返回。
    };
    Q_ENUM(WindowOrder)
//   Q_PROPERTY(WindowOrder    activationOrder   //默认情况下,它是窗口创建顺序。
//              READ           activationOrder   WRITE     setActivationOrder)
                WindowOrder    activationOrder() const;
                void        setActivationOrder(WindowOrder order);

    //这个枚举描述了区域的视图模式,即子窗口将如何显示。
    enum ViewMode {
        SubWindowView, //显示带有窗口框架的子窗口(默认)
        TabbedView  //在标签栏中显示带有标签的子窗口。此时,非常类似于标签窗体 QTabWidget
    };
    Q_ENUM(ViewMode)
//   Q_PROPERTY(ViewMode       viewMode          //默认情况下,使用SubWindowView来显示子窗口。
//              READ           viewMode          WRITE     setViewMode)
                ViewMode       viewMode() const;
                void        setViewMode(ViewMode mode);


//   Q_PROPERTY(bool           documentMode      //在标签视图模式下,默认禁用文档模式。F
//              READ           documentMode      WRITE     setDocumentMode)
                bool           documentMode() const;
                void        setDocumentMode(bool enabled);


//   Q_PROPERTY(bool           tabsClosable      //在标签视图模式下,默认不使用关闭按钮。
//              READ           tabsClosable      WRITE     setTabsClosable)
                bool           tabsClosable() const;
                void        setTabsClosable(bool closable);


//   Q_PROPERTY(bool           tabsMovable       //标签默认情况下不可移动。
//              READ           tabsMovable       WRITE     setTabsMovable)
                bool           tabsMovable() const;
                void        setTabsMovable(bool movable);


//   Q_PROPERTY(QTabWidget::TabShape        tabShape //标签页视图模式下的形状,默认是 Rounded
//              READ                        tabShape
//              WRITE                    setTabShape)
                QTabWidget::TabShape        tabShape() const;
                void                     setTabShape(QTabWidget::TabShape shape);


// //enum QTabWidget::TabPosition { North, South, West, East };
//   Q_PROPERTY(QTabWidget::TabPosition     tabPosition //默认北方
//              READ                        tabPosition
//              WRITE                    setTabPosition)
                 QTabWidget::TabPosition    tabPosition() const;
                void                     setTabPosition(QTabWidget::TabPosition position);


    QSize        sizeHint() const override;
    QSize minimumSizeHint() const override;

    //此枚举描述了自定义QMdiArea行为的选项。
    enum AreaOption {
        DontMaximizeSubWindowOnActivation = 0x1 //当活动子窗口被最大化时,
        //默认行为是最大化下一个被激活的子窗口。如果您不希望出现这种行为,请设置此选项。
    };
    Q_DECLARE_FLAGS(AreaOptions, AreaOption)
    bool    testOption(AreaOption opton) const;
    void     setOption(AreaOption option, bool on = true);

    //返回MDI区域中所有子窗口的列表。
    //如果顺序为“创建顺序”(默认值),则窗口将按照它们被插入工作区的顺序排序。
    //如果顺序为“堆叠顺序”,则窗口将按照其堆叠顺序列出,最顶部的窗口将作为列表中的最后一个项。
    //如果顺序为“激活历史顺序”,则窗口将按照其最近的激活历史列出。
    QList<QMdiSubWindow *>        subWindowList(WindowOrder order = CreationOrder) const;
    //返回当前子窗口的指针,如果没有当前子窗口则返回nullptr。
    //如果包含QMdiArea的QApplication处于活动状态,此函数将返回与activeSubWindow()相同的结果。
    QMdiSubWindow       *  currentSubWindow() const;
    QMdiSubWindow       *   activeSubWindow() const;
    //返回当前活动子窗口的指针。如果当前没有活动窗口,则返回nullptr。
    //在窗口状态方面,子窗口被视为顶层窗口,
    //即如果MDI区域之外的某个小部件是活动窗口,则没有子窗口会处于活动状态。
    //请注意,如果MDI区域所在的窗口中的某个小部件获得焦点,该窗口将被激活

    /*
    QMdiArea mdiArea;
    QMdiSubWindow * subWindow1 = new QMdiSubWindow;
    subWindow1->setWidget(internalWidget1);
    subWindow1->setAttribute(Qt::WA_DeleteOnClose);
    mdiArea.addSubWindow(subWindow1);

    QMdiSubWindow * subWindow2 = mdiArea.addSubWindow(internalWidget2);
    */
    //将小部件作为MDI区域的新子窗口添加。如果windowFlags非零,它们将覆盖设置在小部件上的标志。
    //这个小部件可以是 QMdiSubWindow 或是其他 QWidget
    //(如果是后者,MDI区域将创建一个子窗口并将该小部件设置为内部小部件)
    //注意:一旦子窗口被添加,其父级将变为QMdiArea的视口小部件。
    //当您创建自己的子窗口时,如果希望该窗口在MDI区域关闭时被删除,则必须设置Qt::WADeleteOnClose窗口属性。
    //否则,该窗口将被隐藏,而MDI区域将不会激活下一个子窗口。 返回添加到MDI区域的QMdiSubWindow。
    QMdiSubWindow       *      addSubWindow(QWidget * widget,
                                            Qt::WindowFlags flags = Qt::WindowFlags());
    void                    removeSubWindow(QWidget * widget);
    //从MDI区域中移除小部件。这个小部件必须要么是QMdiSubWindow,要么是一个子窗口的内部小部件。
    //请注意,QMdiArea实际上从未真正删除过小部件。
    //如果传递的是QMdiSubWindow,则其父对象被设为nullptr并移除;
    //但如果传递的是内部小部件,则其子小部件被设为nullptr,而MdiSubWindow并不会被移除。

Q_SIGNALS:
    //QMdiArea 在窗口 window被激活后发出此信号。
    //当window为 nulptr 时,QMdiArea刚刚使其最后一个激活的窗口失效,工作区上不存在任何激活的窗口。
    void subWindowActivated(QMdiSubWindow * window);


public Q_SLOTS:
    void             tileSubWindows(); //将所有子窗口以平铺模式排列。
    void          cascadeSubWindows(); //将所有子窗口以级联模式排列。
    //激活子窗口 window。如果窗口 window为nullptr,则任何当前活动窗口将被停用。
    void        setActiveSubWindow (QMdiSubWindow * window);
    //被激活的窗口将是按照当前激活顺序 activation order确定的下一个窗口。
    void     activateNextSubWindow (); //将键盘焦点切换到子窗口列表中的另一个窗口。
    void activatePreviousSubWindow (); //将键盘焦点切换到子窗口列表中的另一个窗口。
    void      closeActiveSubWindow (); //Closes the active subwindow.
    void         closeAllSubWindows(); //通过向每个窗口发送QCloseEvent来关闭所有子窗口。
    //在子窗口关闭之前,您可能会接收到子窗口激活()信号(如果MDI区域在另一个窗口关闭时激活了该子窗口).
    //忽略关闭事件的子窗口将保持打开状态。

protected Q_SLOTS:
    //Reimplements: QAbstractScrollArea::setupViewport(QWidget *viewport).
    void setupViewport(QWidget * viewport) override;
    //这个槽在`setViewport()、被调用后由`QAbstractScrollArea`调用。
    //在`QMdiArea`的子类中重写此函数以便在开始使用新视口 viewport之前进行初始化。

protected:
    void scrollContentsBy(int dx, int dy) override;
    bool         eventFilter(QObject * object, QEvent *event) override;
    bool         event(QEvent       *       event) override;
    void    paintEvent(QPaintEvent  *  paintEvent) override;
    void    childEvent(QChildEvent  *  childEvent) override;
    void   resizeEvent(QResizeEvent * resizeEvent) override;
    void    timerEvent(QTimerEvent  *  timerEvent) override;
    void     showEvent(QShowEvent   *   showEvent) override;
    bool viewportEvent(QEvent       *       event) override;


}; //完结 class QMdiArea : public QAbstractScrollArea

Q_DECLARE_OPERATORS_FOR_FLAGS(QMdiArea::AreaOptions)

QT_END_NAMESPACE

#endif // QMDIAREA_H

(7)

谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值