Qt入门系列开发教程【基础控件篇】QMainWindow主窗口

举报
鱼酱 发表于 2022/02/25 08:47:15 2022/02/25
【摘要】 @[toc] 描述主窗口为构建应用程序的用户界面提供了一个框架。 Qt 有 QMainWindow 及其相关的主窗口管理类。 QMainWindow 有自己的布局,您可以在其中添加 QToolBars、QDockWidgets、QMenuBar 和 QStatusBar。 布局有一个中心区域,可以被任何类型的小部件占据。 您可以在下面看到布局的图像。注意:不支持创建没有中央小部件的主窗口。 ...

@[toc]

描述

主窗口为构建应用程序的用户界面提供了一个框架。 Qt 有 QMainWindow 及其相关的主窗口管理类。 QMainWindow 有自己的布局,您可以在其中添加 QToolBars、QDockWidgets、QMenuBar 和 QStatusBar。 布局有一个中心区域,可以被任何类型的小部件占据。 您可以在下面看到布局的图像。
在这里插入图片描述

注意:不支持创建没有中央小部件的主窗口。 即使它只是一个占位符,您也必须有一个中央小部件

创建主窗口组件

中央部件通常是标准的 Qt 部件,例如 QTextEdit 或 QGraphicsView。 自定义小部件也可用于高级应用程序。 您可以使用 setCentralWidget() 设置中央小部件。
主窗口具有单个 (SDI) 或多个 (MDI) 文档界面。 您可以使用 QMdiArea 作为中央小部件在 Qt 中创建 MDI 应用程序。
我们现在将检查可以添加到主窗口的每个其他小部件。 我们举例说明如何创建和添加它们。

     void MainWindow::createMenus()
     {
         fileMenu = menuBar()->addMenu(tr("&File"));
         fileMenu->addAction(newAct);
         fileMenu->addAction(openAct);
         fileMenu->addAction(saveAct);
      }

createPopupMenu() 函数在主窗口接收到上下文菜单事件时创建弹出菜单。 默认实现会生成一个菜单,其中包含来自停靠小部件和工具栏的可检查操作。 您可以为自定义菜单重新实现 createPopupMenu()。

创建工具栏

工具栏在 QToolBar 类中实现。 使用 addToolBar() 将工具栏添加到主窗口。
您可以通过将工具栏分配给特定的 Qt::ToolBarArea 来控制工具栏的初始位置。 您可以通过插入工具栏分隔符来分割区域 - 将其视为文本编辑中的换行符 - 使用 addToolBarBreak() 或 insertToolBarBreak()。 您还可以使用 QToolBar::setAllowedAreas() 和 QToolBar::setMovable() 限制用户放置。
可以使用 iconSize() 检索工具栏图标的大小。 尺寸取决于平台; 您可以使用 setIconSize() 设置固定大小。 您可以使用 setToolButtonStyle() 更改工具栏中所有工具按钮的外观。
工具栏创建示例如下:

     void MainWindow::createToolBars()
     {
         fileToolBar = addToolBar(tr("File"));
         fileToolBar->addAction(newAct);
    }

创建 Dock 小部件

Dock 小部件在 QDockWidget 类中实现。 停靠小部件是可以停靠在主窗口中的窗口。 您可以使用 addDockWidget() 将停靠小部件添加到主窗口。
Qt::DockWidgetArea 枚举给出了四个停靠小部件区域:左、右、上和下。 您可以使用 setCorner() 指定哪个停靠小部件区域应占据区域重叠的角落。 默认情况下,每个区域只能包含一行(垂直或水平)停靠小部件,但如果您使用 setDockNestingEnabled() 启用嵌套,则可以在任一方向添加停靠小部件。
两个停靠小部件也可以相互堆叠。 然后使用 QTabBar 选择应该显示哪些小部件。
我们举例说明如何创建停靠小部件并将其添加到主窗口:

     QDockWidget *dockWidget = new QDockWidget(tr("Dock Widget"), this);
     dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
                                 Qt::RightDockWidgetArea);
     dockWidget->setWidget(dockWidgetContents);
     addDockWidget(Qt::LeftDockWidgetArea, dockWidget);

状态栏

您可以使用 setStatusBar() 设置状态栏,但在第一次调用 statusBar()(返回主窗口的状态栏)时会创建一个状态栏。 有关如何使用它的信息,请参阅 QStatusBar。
存储状态
QMainWindow 可以使用 saveState() 存储其布局的状态; 稍后可以使用 restoreState() 检索它。 它是存储的工具栏和停靠小部件的位置和大小(相对于主窗口的大小)。

API


#ifndef QDYNAMICMAINWINDOW_H
#define QDYNAMICMAINWINDOW_H

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

QT_REQUIRE_CONFIG(mainwindow);

QT_BEGIN_NAMESPACE

class QDockWidget;
class QMainWindowPrivate;
class QMenuBar;
class QStatusBar;
class QToolBar;
class QMenu;

class Q_WIDGETS_EXPORT QMainWindow : public QWidget
{
    Q_OBJECT

    Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
    Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle READ toolButtonStyle WRITE setToolButtonStyle)
#if QT_CONFIG(dockwidget)
    Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated)
#if QT_CONFIG(tabbar)
    Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode)
#endif // QT_CONFIG(tabbar)
#if QT_CONFIG(tabwidget)
    Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
#endif // QT_CONFIG(tabwidget)
    Q_PROPERTY(bool dockNestingEnabled READ isDockNestingEnabled WRITE setDockNestingEnabled)
#endif // QT_CONFIG(dockwidget)
    Q_PROPERTY(DockOptions dockOptions READ dockOptions WRITE setDockOptions)
#if QT_CONFIG(toolbar)
    Q_PROPERTY(bool unifiedTitleAndToolBarOnMac READ unifiedTitleAndToolBarOnMac
               WRITE setUnifiedTitleAndToolBarOnMac)
#endif

public:
    enum DockOption {
        AnimatedDocks = 0x01,
        AllowNestedDocks = 0x02,
        AllowTabbedDocks = 0x04,
        ForceTabbedDocks = 0x08,  // implies AllowTabbedDocks, !AllowNestedDocks
        VerticalTabs = 0x10,      // implies AllowTabbedDocks
        GroupedDragging = 0x20    // implies AllowTabbedDocks
    };
    Q_ENUM(DockOption)
    Q_DECLARE_FLAGS(DockOptions, DockOption)
    Q_FLAG(DockOptions)
    //构造函数
    explicit QMainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
    //析构函数
    ~QMainWindow();
    
    //工具类icon大小
    QSize iconSize() const;
    void setIconSize(const QSize &iconSize);
    
    //工具栏按钮样式
    Qt::ToolButtonStyle toolButtonStyle() const;
    void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);

#if QT_CONFIG(dockwidget)
    bool isAnimated() const;
    bool isDockNestingEnabled() const;
#endif

#if QT_CONFIG(tabbar)
    bool documentMode() const;
    void setDocumentMode(bool enabled);
#endif

#if QT_CONFIG(tabwidget)
    QTabWidget::TabShape tabShape() const;
    void setTabShape(QTabWidget::TabShape tabShape);
    QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
    void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition);
#endif // QT_CONFIG(tabwidget)
    
    //设置dock配置
    void setDockOptions(DockOptions options);
    DockOptions dockOptions() const;

    bool isSeparator(const QPoint &pos) const;

//菜单栏相关
#if QT_CONFIG(menubar)
    QMenuBar *menuBar() const;
    void setMenuBar(QMenuBar *menubar);

    QWidget  *menuWidget() const;
    void setMenuWidget(QWidget *menubar);
#endif

#if QT_CONFIG(statusbar)
    QStatusBar *statusBar() const;
    void setStatusBar(QStatusBar *statusbar);
#endif
    //获取中心部件
    QWidget *centralWidget() const;
    void setCentralWidget(QWidget *widget);
    //删除中心部件
    QWidget *takeCentralWidget();

#if QT_CONFIG(dockwidget)
    void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
    Qt::DockWidgetArea corner(Qt::Corner corner) const;
#endif

//工具栏相关
#if QT_CONFIG(toolbar)
    void addToolBarBreak(Qt::ToolBarArea area = Qt::TopToolBarArea);
    void insertToolBarBreak(QToolBar *before);

    void addToolBar(Qt::ToolBarArea area, QToolBar *toolbar);
    void addToolBar(QToolBar *toolbar);
    QToolBar *addToolBar(const QString &title);
    void insertToolBar(QToolBar *before, QToolBar *toolbar);
    void removeToolBar(QToolBar *toolbar);
    void removeToolBarBreak(QToolBar *before);

    bool unifiedTitleAndToolBarOnMac() const;

    Qt::ToolBarArea toolBarArea(const QToolBar *toolbar) const;
    bool toolBarBreak(QToolBar *toolbar) const;
#endif // QT_CONFIG(toolbar)

#if QT_CONFIG(dockwidget)
    //添加dock
    void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget);
    void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget,
                       Qt::Orientation orientation);
    //将第一个停靠小部件覆盖的空间分成两部分,将第一个停靠小部件移动到第一部分,并将第二个停靠小部件移动到第二部分。
    void splitDockWidget(QDockWidget *after, QDockWidget *dockwidget,
                         Qt::Orientation orientation);
#if QT_CONFIG(tabbar)
    void tabifyDockWidget(QDockWidget *first, QDockWidget *second);
    QList<QDockWidget*> tabifiedDockWidgets(QDockWidget *dockwidget) const;
#endif
    //删除dock
    void removeDockWidget(QDockWidget *dockwidget);
    //恢复dock
    bool restoreDockWidget(QDockWidget *dockwidget);

    Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const;

    void resizeDocks(const QList<QDockWidget *> &docks,
                     const QList<int> &sizes, Qt::Orientation orientation);
#endif // QT_CONFIG(dockwidget)

    QByteArray saveState(int version = 0) const;
    bool restoreState(const QByteArray &state, int version = 0);

#if QT_CONFIG(menu)
    virtual QMenu *createPopupMenu();
#endif

public Q_SLOTS:
#if QT_CONFIG(dockwidget)
    void setAnimated(bool enabled);
    void setDockNestingEnabled(bool enabled);
#endif
#if QT_CONFIG(toolbar)
    void setUnifiedTitleAndToolBarOnMac(bool set);
#endif

Q_SIGNALS:
    void iconSizeChanged(const QSize &iconSize);
    void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
#if QT_CONFIG(dockwidget)
    void tabifiedDockWidgetActivated(QDockWidget *dockWidget);
#endif

protected:
#ifndef QT_NO_CONTEXTMENU
    void contextMenuEvent(QContextMenuEvent *event) override;
#endif
    //事件函数
    bool event(QEvent *event) override;

private:
    Q_DECLARE_PRIVATE(QMainWindow)
    Q_DISABLE_COPY(QMainWindow)
};

Q_DECLARE_OPERATORS_FOR_FLAGS(QMainWindow::DockOptions)

QT_END_NAMESPACE

#endif // QDYNAMICMAINWINDOW_H

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。