0. 概述
Qt窗口是通过 QMainWindow类 来实现的。
QMainWindow 是一个为用户提供主窗口程序的类,继承自QWidget类,并且提供了一个预定义的布局。QMainWindow包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个浮动窗口(铆接部件)(dock widgets)、一个状态栏(status bar)和一个中心部件(central widget),它是许多应用程序的基础,如文本编辑器,图片编辑器等。下图为QMainwindow中,各组件所处的位置:
1. 菜单栏
Qt中的菜单栏是通过 QMenuBar 类来实现的,一个主窗口最多只能有一个菜单栏,位于主窗口顶部、主窗口标题栏下。
菜单栏中包含菜单,菜单中包含菜单项,示例:
1.1 菜单栏创建
方式一:菜单栏的创建可以借助于 QMainWindow类 提供的 menuBar() 函数来实现。menubar()函
数原型如下:
方式二:在堆上动态创建
注意:如果创建项目时勾选了自动生成ui文件,此时ui中默认创建的QMainWindow中已经存在QMenuBar, 此时我们手动创建新的QMenuBar使用this->setMenuBar(menubar)替换,会导致原有的QMenuBar脱离对象树,导致内存泄漏。
建议创建方式:
QMenuBar *menubar = this->menuBar();
this->setMenuBar(menubar);
- 如果QMenuBar 已存在,this->menuBar()会返回当前窗口的QMenuBar
- 如果QMenuBar 不存在,this->menuBar()会先创建一个QMenuBar再返回
1.2 菜单创建
创建菜单栏后,通过QMenuBar提供的addMenu函数添加菜单:
1.3 菜单项创建
在Qt中,并没有专门的菜单项类,可以通过 QAction 类,抽象出公共的动作,如在菜单中添加菜单项。(QAction可以在菜单栏中使用,也可以在工具栏中使用)
1.4 菜单项快捷键
通过在文本中添加&F,就添加了快捷键alt+F,其中&符合并不会在界面上显示。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);QMenuBar *menubar = new QMenuBar();this->setMenuBar(menubar);QMenu *menu1 = new QMenu("文件 (&A)");QMenu *menu2 = new QMenu("编辑 (&B)");QMenu *menu3 = new QMenu("构建 (&C)");menubar->addMenu(menu1);menubar->addMenu(menu2);menubar->addMenu(menu3);QAction *action1 = new QAction("打开 (&F)");QAction *action2 = new QAction("创建 (&D)");QAction *action3 = new QAction("关闭 (&E)");menu1->addAction(action1);menu1->addAction(action2);menu1->addAction(action3);connect(menu1, &QMenu::aboutToShow, this, &MainWindow::handl1);connect(action1, &QAction::triggered, this, &MainWindow::handl2);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::handl1()
{qDebug() << "hand1";
}void MainWindow::handl2()
{qDebug() << "hand2";
}
1.5 菜单项分割线
在菜单项之间,可以使用 QMenu提供的addSeparator()函数来添加分割线:
1.6 子菜单创建
使用QMenu的addMenu(QMenu *menu)函数,可以为菜单添加子菜单,子菜单添加可以嵌套:
1.7 菜单图标
通过setIcon(const QIcon &icon)函数可以为菜单、菜单项添加图标。
给菜单QMenu设置图标:
- QMenu位于QMenuBar中:此时文本不显示,只显示图标
- QMenu位于子菜单中:图标和文本均显示
2. 工具栏
工具栏是应用程序中集成各种功能实现快捷键使用的一个区域。工具栏并不是应用程序中必须存在的组件,可以有多个,也可以没有。工具栏是一个可移动的组件,它的元素可以是各种窗口组件,通常以图标按钮的形式存在。示意图:
2.1 工具栏创建
通过QMainWindow类的addToolBar()函数来创建工具栏,每增加一个工具栏都需要调用一次该函数。
2.2 设置停靠位置
工具栏停靠位置的设置有两种方式:一种是在创建工具栏的同时指定停靠位置,另一种是通过QToolBar类提供的setAllowedAreas()函数来设置。可设置的停靠位置:
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠
注意:在创建工具栏的同时指定其停靠位置,指的是程序运行时工具栏默认所在位置;使用setAllowedAreas()函数设置停靠位置,指的是工具栏允许其所能停靠的位置。
2.3 设置浮动属性
工具栏的浮动属性可以通过QToolBar类提供的setFloatable()函数来设置。
函数原型:
void setFloatable(bool floatable);
参数:
floatable:true浮动,false不浮动
2.4 设置移动属性
通过QToolBar类提供的setMovable()函数设置工具栏的移动属性。
函数原型:
void setMovable(bool movable);
参数:
movable:true移动,false不移动
说明:
若工具栏为不可移动状态,则设置其停靠位置的操作就不会生效,所以设置工具栏的移动属性类似于总开关的效果。
3. 状态栏
状态栏是应用程序中输出简要信息的区域,一般位于主窗口最底部,一个窗口中最多只能有一个状态栏。在Qt中,状态栏是通过QStatusBar类实现的,在状态栏中可以显示的消息类型有:
- 实时消息:如当前程序状态
- 永久消息:如程序版本号、机构名称
- 进度消息:如进度条提示,百分比提示
3.1 状态栏显示消息
void showMessage(const QString &text, int timeout = 0);
showMessage函数用于显示窗口消息,timeout参数表示消息显示时间,单位毫秒。0表示永久显示。
3.2 状态栏显示控件
状态栏也可以正常添加控件显示:
4. 浮动窗口
在Qt中,浮动窗口也称为铆接部件。浮动窗口是通过QDockWidget类来实现浮动的功能。浮动窗口一般位于核心部件周围,可以有多个。
4.1 浮动窗口创建
通过QDockWidget类构造函数动态创建浮动窗口,使用addDockWidget接口将浮动窗口添加到当前窗口中:
void addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget);
DockWidgetArea取值:
enum DockWidgetArea {
LeftDockWidgetArea = 0x1,
RightDockWidgetArea = 0x2,
TopDockWidgetArea = 0x4,
BottomDockWidgetArea = 0x8,
DockWidgetArea_Mask = 0xf,
AllDockWidgetAreas = DockWidgetArea_Mask,
NoDockWidgetArea = 0
};
4.2 浮动窗口添加控件
不能之间给浮动窗口添加子控件,需要创建一个单独的QWidget,然后把需要添加的控件加入到QWidget中,最后在把QWidget设置到DockWidget中。(DockWidget只能包含一个QWidget)
4.3 浮动窗口允许停靠位置
void setAllowedAreas(Qt::DockWidgetAreas areas);
enum DockWidgetArea {
LeftDockWidgetArea = 0x1,
RightDockWidgetArea = 0x2,
TopDockWidgetArea = 0x4,
BottomDockWidgetArea = 0x8,
DockWidgetArea_Mask = 0xf,
AllDockWidgetAreas = DockWidgetArea_Mask,
NoDockWidgetArea = 0
};
多个位置使用‘|’进行设置:
5. 对话框
5.1 简介
对话框是GUI程序中不可或缺的组成部分。一些不合适在主窗口实现的功能组件可以设置在对话框中。对话框通常是一个顶层窗口,出现在程序的最上层,用于实现短期认为或者简洁的用户交互。
Qt常用的内置对话框有:QFileDialog(文件对话框)、QColorDialog(颜色对话框)、QFontDialog(字体对话框)、QInputDialog(输入对话框)、QMessageBox(消息框)。
5.2 对话框分类
对话框分为 模态对话框 和 非模态对话框。
5.2.1 模态对话框
模态对话框:显示后无法与父窗口进行交互,是一种阻塞式对话框。使用QDialog::exec()函数调用。
模态对话框适用于必须依赖用户选择的场景,比如消息显示、文件选择、打印设置等。
5.2.2 非模态对话框
非模态对话框显示后独立存在,可以同时与父窗口进行交互,是一种非阻塞式对话框,使用QDialog::show()函数调用。
注意:非模态对话框一般在堆上创建,因为如果在栈上创建,弹出的非模态对话框就会一闪而过。同时还需要设置Qt::WA_DeleteOnClose属性,目的是当创建多个非模态对话框时,为了避免内存泄漏。
非模态对话框适用于特殊功能设置场合,比如查找操作,属性设置等。
5.2.3 混合属性对话框
混合属性对话框同时具有模态对话框和非模态对话框的属性,对话框的生成和销毁具有非模态对话框属性,功能上具体模态对话框属性。
使用QDialog::setModal()函数可以创建混合特性的对话框。通常,窗口对话框时需要指定对话框的父组件。
void setModal(bool modal);
modal:true模态,false非模态
注意:
(1)使用exec调用会忽略modal属性值,默认为模态对话框;使用show调用会根据modal属性值,确认对话框是模态还是非模态。
(2)使用exec调用会阻塞运行,直到对话框关闭返回;使用show调用不会阻塞当前运行。
5.2.4 自定义对话框创建
在项目中右键添加新文件=> Qt => Qt 设计器界面类
根据需要选择界面模板
设置自定义对话框类名,该类默认继承自QDialog
5.3 Qt内置对话框
Qt提供了多种可复用的对话框类型,即Qt标准对话框。Qt标准对话框全部继承自QDialog类,常用标准对话框如下:
5.3.1 消息对话框QMessageBox
消息对话框是应用程序中最常用的界面元素,主要用于为用户提示重要信息,强制用户进行选择操作。
QMessageBox类中定义了静态成员函数,可以直接调用创建不同风格的消息对话框,其中包括:
示例1:动态创建消息对话框
示例2:使用静态函数创建对话框
自定义消息对话框按钮:
void addButton(QAbstractButton *button, ButtonRole role);
enum ButtonRole {
InvalidRole = -1,
AcceptRole,
RejectRole,
DestructiveRole,
ActionRole,
HelpRole,
YesRole,
NoRole,
ResetRole,
ApplyRole,
NRoles
};
5.3.2 颜色对话框QColorDialog
颜色对话框功能是允许用户选择颜色,继承自QDialog类。效果如下:
颜色对话框,实际中更常见的创建方式是直接使用getColor静态函数创建,接口如下:
static QColor getColor(const QColor &initial = Qt::white,
QWidget *parent = nullptr,
const QString &title = QString(),
ColorDialogOptions options = ColorDialogOptions());
参数:
initial:设置初始颜色
parent:设置父对象
title:设置窗口标题
options:设置选项
返回值:
用户选择的颜色的argb值。示例:QColor(ARGB 1, 1, 0.270588, 0.682353)
5.3.3 文件对话框QFileDialog
文件对话框用于应用程序中需要打开一个外部文件或需要将当前内容保存到指定的外部文件。
常用方法介绍:
(1)打开文件(一次只能打开一个文件)
static QString getOpenFileName(QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
Options options = Options());
(2)打开多个文件(一次可以打开多个文件)
static QStringList getOpenFileNames(QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
Options options = Options());
(3)保存文件
static QString getSaveFileName(QWidget *parent = nullptr,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = nullptr,
Options options = Options());
parent:设置父对象
caption:对话框标题
dir:默认打开路径
filter:文件过滤器
5.3.4 字体对话框QFontDialog
Qt提供了预定义的字体对话框QFontDialog,用于提供选择字体的对话框部件,效果如下:
常用接口:
static QFont getFont(bool *ok, QWidget *parent = nullptr);
ok:获取用户是否点击ok
5.3.5 输入对话框QInputDialog
Qt中提供了预定义的输入对话框类QInputFialog,用于进行临时数据输入场景,效果如下:
(1)输入数值
static int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0,
int minValue = -2147483647, int maxValue = 2147483647,
int step = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());
static double getDouble(QWidget *parent, const QString &title, const QString &label, double value = 0,double minValue = -2147483647, double maxValue = 2147483647,
int decimals = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags(),
double step = 1);
title:设置对话框标题
label:设置提示信息
value:设置默认值
(2)条目输入框
static QString getItem(QWidget *parent, const QString &title, const QString &label,
const QStringList &items, int current = 0, bool editable = true,
bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags(),
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
items:设置的可以选择条目
注:用户可直接选择预定义的选项条目,也可以直接输入其他内容
(3)文本输入框
static QString getText(QWidget *parent, const QString &title, const QString &label,
QLineEdit::EchoMode echo = QLineEdit::Normal,
const QString &text = QString(), bool *ok = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags(),
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
(4)多行文本框
static QString getMultiLineText(QWidget *parent, const QString &title, const QString &label,
const QString &text = QString(), bool *ok = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags(),
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);