目录
- 简介
- UI布局元素
- Central Widget
- Menu Bar
- Toolbars
- Status Bar
- Dock Widgets
- 参考文档
简介
如下图所示,我们常见的一些desktop软件,比如VS Code、Smart VCI等,一般都会包含顶部的菜单栏,底部的状态栏,以及一些其他UI布局元素。
新建Qt项目是以MainWindow
作为显示的载体,MainWindow
是继承自QMainWindow
的一个子类。
如下图所示,QMainWindow
本身提供了常用的UI布局元素1,包括:
- Menu Bar 菜单栏
- Toolbars 工具栏
- Status Bar 状态栏
- Dock Widgets Dock栏
- Central Widget 页面内容区域
合理利用这几种元素,我们就可以构建出我们常见的desktop布局了:
接下来我们一次介绍这些元素及其基本使用方法
UI布局元素
Central Widget
Central Widget主要用来显示页面内容,通常是自定义Widget,也就是QWidget
的子类,用来展示我们App的主要内容。可以调用QMainWindow
的setCentralWidget()
方法来设置Central Widget。
Menu Bar
Menu Bar也就是我们常见的菜单栏,在Qt中是用QMenuBar
2类创建的。
在介绍QMenuBar
之前,需要先介绍另外一个类QAction
3。在desktop应用中,经常通过菜单栏中的菜单、工具栏按钮或者快捷键调用一些应用中常用的功能,比如打开文件操作。对于同一个功能,不管通过什么方式调用,执行的命令应该是同一个。这种情况下把功能抽象为Action是非常有用的,在Qt中,就是QAction
。也就是说QAction
是某个应用功能的抽象,可以同时被添加到菜单栏、工具栏和快捷键,Qt会自动完成在不同地方的状态同步。以下面代码为例:
// ...
QAction *submenu4 = new QAction("子菜单四");
submenu4->setCheckable(true);
submenu4->setShortcuts(QKeySequence::Copy);
// ...
menubar->addAction(submenu4);
toolbar->addAction(submenu4);
如果在应用中执行“Ctrl + C”, 子菜单四就会被选中,菜单栏、工具栏中的子菜单四状态都会同时发生改变:
接下来可以开始介绍QMenuBar
了,它的功能就是创建菜单栏,容纳QMenu
4。通过QMainWinow
的void setMenuBar(QMenuBar *menuBar)
5功能添加菜单栏,通过QMenuBar
的addMenu
6方法为菜单栏添加菜单元素,通过addAction
方法添加具体命令。
通过下面例子介绍具体使用:
QMenuBar *menubar = new QMenuBar();
// 创建多级菜单
QMenu *menu1 = new QMenu("菜单一");
QMenu *submenu1 = new QMenu("子菜单一");
QAction *submenu11 = new QAction("二级子菜单一");
QAction *submenu12 = new QAction("二级子菜单二");
submenu1->addAction(submenu11);
submenu1->addAction(submenu12);
QAction *submenu2 = new QAction("子菜单二");
menu1->addMenu(submenu1);
menu1->addAction(submenu2);
// 没有子菜单的一级菜单
QAction *menu2 = new QAction("菜单二");
menubar->addMenu(menu1);
menubar->addAction(menu2);
效果如下图
Toolbars
与菜单栏类似,Qt通过QToolBar
7创建工具栏,通过QMainWindow
的void addToolBar(QToolBar *toolbar)
8可以为窗口添加工具栏,一个窗口中可以添加多个工具栏。
工具栏元素可以添加QAction
也可以添加QWidget
,对应添加方法是addAction()
、addWidget()
。QMainWindow
添加工具栏时可以指定工具栏的默认位置,通过下面的例子介绍具体使用
QAction *submenu2 = new QAction("子菜单二");
QAction *submenu3 = new QAction("子菜单三");
QAction *submenu4 = new QAction("子菜单四");
QPushButton *btn = new QPushButton("按钮");
QToolBar *toolbar = new QToolBar();
toolbar->addAction(submenu2);
toolbar->addAction(submenu3);
toolbar->addSeparator(); // 菜单元素之间增加分割线
toolbar->addWidget(btn);
QToolBar *toolbar2 = new QToolBar();
toolbar2->addAction(submenu4);
addToolBar(toolbar);
addToolBar(toolbar2);
效果如图:
菜单栏默认会被添加在窗口上方,菜单栏默认也是可以拖动到窗口的四个边,也可以处于悬浮状态
对于上述的默认值,可以手动做一些限制和调整:
- 指定初始位置,在调用
addToolBar()
时指定位置,比如addToolBar(toolbar, Qt::TopToolBarArea)
。位置包括LeftToolBarArea
、RightToolBarArea
、TopToolBarArea
、BottomToolBarArea
。 - 是否允许多动,通过
QToolBar
的void setMovable(bool movable)
- 指定可以拖动到的窗口位置,通过
QToolBar
的void setAllowedAreas(Qt::ToolBarAreas areas)
,比如只允许窗口上方或者窗口下方toolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);
- 菜单栏是否可以处于悬浮状态,通过
QToolBar
的void setFloatable(bool floatable)
Status Bar
通过QStatusBar
9为窗口添加状态栏,位于窗口底部,一般用于显示一些通知和提示。QMainWindow
的setStatusBar()
函数为窗口设置状态栏。
通过statusBar()->showMessage("Message", 2000);
在状态栏显示信息,并支持指定信息存在的时长。
Dock Widgets
相比于QToolBar
,Dock Widgets10的内容有更多自由度,一般用于显示一些工作区域,比如文档目录这些。通过QMainWindow
的addDockWidget
为窗口添加Dock Widget。
和工具栏类似,Dock Widget也可以指定初始位置、是否可以拖动、允许的位置以及是否可以处于悬浮状态等。
同一个窗口同样可以添加多个Dock Widget,多个Widget还可以组合在一起,通过tab切换
通过如下示例说明:
QDockWidget *dockWidget = new QDockWidget("Dock Widget");
QLabel *dockWidgetContent = new QLabel("dock Widget内容");
dockWidgetContent->setStyleSheet("background-color:green;color: white;");
dockWidget->setWidget(dockWidgetContent);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
QDockWidget *dockWidget2 = new QDockWidget("Dock Widget 2");
QLabel *dockWidgetContent2 = new QLabel("dock Widget 2 内容");
dockWidgetContent2->setStyleSheet("background-color:green;color: white;");
dockWidget2->setWidget(dockWidgetContent2);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget2);
QDockWidget *dockWidget3 = new QDockWidget(tr("Dock Widget 3"));
dockWidget3->setAllowedAreas(Qt::LeftDockWidgetArea |
Qt::RightDockWidgetArea);
QLabel *dockWidgetContent3 = new QLabel("dock Widget 3 内容");
dockWidgetContent3->setStyleSheet("background-color:green;color: white;");
dockWidget3->setWidget(dockWidgetContent3);
addDockWidget(Qt::LeftDockWidgetArea, dockWidget3);
tabifyDockWidget(dockWidget, dockWidget2); // 将dockWidget和dockWidget2组合
tabifyDockWidget(dockWidget, dockWidget3); // 将docketWidget、dockWidget2以及dockWidget3组合在一起
效果如下图:
参考文档
https://doc.qt.io/qt-6/qmainwindow.html#qt-main-window-framework ↩︎
https://doc.qt.io/qt-6/qmenubar.html ↩︎
https://doc.qt.io/qt-6/qaction.html ↩︎
https://doc.qt.io/qt-6/qmenu.html ↩︎
https://doc.qt.io/qt-6/qmainwindow.html#setMenuBar ↩︎
https://doc.qt.io/qt-6/qmenubar.html#addMenu-1 ↩︎
https://doc.qt.io/qt-6/qtoolbar.html ↩︎
https://doc.qt.io/qt-6/qmainwindow.html#addToolBar-1 ↩︎
https://doc.qt.io/qt-6/qstatusbar.html ↩︎
https://doc.qt.io/qt-6/qdockwidget.html#details ↩︎