【QT】Qt 窗口 (QMainWindow)
Qt 窗口
- 一、菜单栏
- 1. 创建菜单栏并添加菜单
- 2. 创建菜单项
- 3. 综合示例
- 二、工具栏
- 1. 创建工具栏
- 2. 设置停靠位置
- 3. 设置浮动属性
- 4. 综合示例
- 三、状态栏
- 1. 状态栏的创建
- 2. 在状态栏中显示实时消息
- 3. 在状态栏中显示永久消息
- 四、浮动窗口
- 1. 浮动窗口的创建
- 2. 设置停靠的位置
- 五、对话框
- 1. 对话框介绍
- 2. 对话框分类
- 3. Qt 内置对话框
Qt 窗口是通过 QMainWindow类 来实现的。
QMainWindow 是一个为用户提供主窗口程序的类,继承自 QWidget 类,并且提供了一个预定义的布局。QMainWindow 包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个浮动窗口(铆接部件)(dock widgets)、⼀个状态栏(status bar) 和⼀个 中心部件(central widget),它是许多应用程序的基础,如文本编辑器,图片编辑器等。如下图为 QMainwindow 中 各组件所处的位置:
一、菜单栏
Qt 中的菜单栏是通过 QMenuBar 这个类来实现的。⼀个主窗口最多只有⼀个菜单栏。位于主窗口顶部、主窗⼝标题栏下面。
菜单栏中包含菜单. 菜单中包含菜单项.
1. 创建菜单栏并添加菜单
菜单栏的创建可以借助于 QMainWindow类 提供的 menuBar() 函数来实现。创建菜单,并通过 QMenu 提供的 addMenu() 函数 来添加菜单。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 创建菜单栏 // QMenuBar* menubar = menuBar(); QMenuBar* menubar = new QMenuBar(this); this->setMenuBar(menubar); // 添加菜单 QMenu* menu1 = new QMenu("文件"); QMenu* menu2 = new QMenu("保存"); QMenu* menu3 = new QMenu("编辑"); menubar->addMenu(menu1); menubar->addMenu(menu2); menubar->addMenu(menu3); }
2. 创建菜单项
在 Qt 中,并没有专⻔的菜单项类,可以通过 QAction 类,抽象出公共的动作。如在菜单中添加菜单项.
QAction 可以给菜单栏使⽤, 也可以给⼯具栏使⽤.
修改 mainwindow.cpp :
// 添加菜单项 QAction* action1 = new QAction("save"); QAction* action2 = new QAction("quit"); QAction* action3 = new QAction("open"); menu1->addAction(action1); menu1->addAction(action2); menu1->addAction(action3);
在菜单项之间可以添加分割线。分割线如下图所⽰,添加分割线是通过 QMenu 类 提供的 addSeparator() 函数来实现:
menu1->addAction(action1); menu1->addSeparator(); menu1->addAction(action2); menu1->addSeparator(); menu1->addAction(action3);
3. 综合示例
在窗⼝上创建⼀个菜单栏,在菜单栏中添加⼀些菜单,在某⼀个菜单中添加⼀些菜单项。
(1)在 “mainwindow.cpp” ⽂件中创建菜单和中央控件
-
创建⼀个菜单栏, ⼀个菜单.
-
两个菜单项: 保存, 加载
-
创建⼀个 QTextEdit 作为窗⼝的中央控件.
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 设置标题 this->setWindowTitle("记事本"); // 创建菜单栏 QMenuBar* menubar = new QMenuBar(this); this->setMenuBar(menubar); // 创建菜单 QMenu* menu = new QMenu("文件"); menubar->addMenu(menu); // 创建菜单项 QAction* action1 = new QAction("保存"); QAction* action2 = new QAction("加载"); menu->addAction(action1); menu->addAction(action2); // 创建中央控件,添加 edit 为成员变量,方便后面使用 edit = new QTextEdit(this); this->setCentralWidget(edit); edit->setPlaceholderText("此处编写文本内容"); }
(2)给 action 添加⼀些动作
// 连接信号槽, 点击 action 时触发⼀定的效果. connect(action1, &QAction::triggered, this, &MainWindow::save); connect(action2, &QAction::triggered, this, &MainWindow::load);
实现这两个槽函数:
- 使⽤ QFileDialog 来实现选择⽂件的效果.
getSaveFileName ⽤于保存⽂件的场景. 此时的对话框可以输⼊⽂件名.
getOpenFileName ⽤于打开⽂件的场景. 此时的对话框可以获取到⿏标选择的⽂件名.
-
搭配 C++ 标准库的⽂件操作实现⽂件读写.
void MainWindow::save() { // 弹出对话框,选择写入文件的路径 QFileDialog* dialog = new QFileDialog(this); QString fileName = dialog->getSaveFileName(this, "保存文件", "D:/QtProject"); // 写入文件 std::ofstream file(fileName.toStdString().c_str()); if(!file.is_open()){ qDebug() toPlainText(); file getOpenFileName(this, "加载文件", "D:/QtProject"); // 读取文件 std::ifstream file(fileName.toStdString().c_str()); if(!file.is_open()){ qDebug() setPlainText(text); }
二、工具栏
⼯具栏是应⽤程序中集成各种功能实现快捷键使⽤的⼀个区域。可以有多个,也可以没有,它并不是应⽤程序中必须存在的组件。它是⼀个可移动的组件,它的元素可以是各种窗⼝组件,它的元素通常以图标按钮的⽅式存在。如下图为⼯具栏的⽰意图:
1. 创建工具栏
调⽤ QMainWindow类 的 addToolBar() 函数来创建⼯具栏,每增加⼀个⼯具栏都需要调⽤⼀次该函数。
如添加两个工具栏:
QToolBar* toolbar1 = new QToolBar(this); QToolBar* toolbar2 = new QToolBar(this); this->addToolBar(toolbar1); this->addToolBar(toolbar2);
2. 设置停靠位置
⼯具栏停靠位置的设置有两种⽅式。⼀种是在创建⼯具栏的同时指定停靠的位置,另⼀种是通过 QToolBar类提供的 setAllowedAreas()函数 来设置。
⽅式⼀:创建⼯具栏的同时指定其停靠的位置。
在创建⼯具栏的同时,也可以设置⼯具栏的位置,其默认位置是在窗⼝的最上⾯;如上述代码,默认在最上⾯显⽰。⼯具栏允许停靠的区域由 QToolBar类 提供的 allowAreas()函数 决定,其中可以设置的位置包括:
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠
示例:
QToolBar* toolbar1 = new QToolBar(this); QToolBar* toolbar2 = new QToolBar(this); this->addToolBar(Qt::LeftToolBarArea, toolbar1); this->addToolBar(Qt::RightToolBarArea, toolbar2);
⽅式⼆:使⽤ QToolBar类 提供的 setAllowedAreas()函数 设置停靠位置。如下⽰例:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QToolBar* toolbar1 = new QToolBar(this); QToolBar* toolbar2 = new QToolBar(this); // this->addToolBar(Qt::LeftToolBarArea, toolbar1); // this->addToolBar(Qt::RightToolBarArea, toolbar2); this->addToolBar(toolbar1); this->addToolBar(toolbar2); // 只允许在左侧停靠 toolbar1->setAllowedAreas(Qt::LeftToolBarArea); // 只允许在右侧停靠 toolbar2->setAllowedAreas(Qt::RightToolBarArea); }
3. 设置浮动属性
⼯具栏的浮动属性可以通过 QToolBar 类 提供的 setFloatable() 函数 来设置。setFloatable() 函数原型为:
void setFloatable (bool floatable) 参数: true:浮动 false:不浮动
示例:
toolbar1->setFloatable(true); toolbar2->setFloatable(false);
4. 综合示例
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); resize(800, 600); QToolBar* toolBar = new QToolBar(this); // 设置工具栏的位置,默认是在窗口的上面,此处设置在左侧 addToolBar(Qt::LeftToolBarArea, toolBar); // 设置工具栏的停靠位置,设置工具栏只允许在左右停靠 toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); // 设置工具栏的浮动属性 toolBar->setFloatable(false); // 设置工具栏的移动(总开关) toolBar->setMovable(false); // 设置工具栏内容 QAction* openAction = new QAction("open", this); QAction* newAction = new QAction("new", this); toolBar->addAction(openAction); toolBar->addSeparator(); toolBar->addAction(newAction); // 工具栏中也可以添加控件 QPushButton* button = new QPushButton("保存", this); toolBar->addSeparator(); toolBar->addWidget(button); }
三、状态栏
状态栏是应⽤程序中输出简要信息的区域。⼀般位于主窗⼝的最底部,⼀个窗⼝中最多只能有⼀个状态栏。在 Qt 中,状态栏是通过 QStatusBar类 来实现的。 在状态栏中可以显⽰的消息类型有:
- 实时消息:如当前程序状态
- 永久消息:如程序版本号,机构名称
- 进度消息:如进度条提⽰,百分百提⽰
1. 状态栏的创建
状态栏的创建是通过 QMainWindow 类 提供的 statusBar() 函数来创建;⽰例如下:
// 创建状态栏 QStatusBar* status = statusBar(); // 将状态栏置于窗口中 setStatusBar(status);
2. 在状态栏中显示实时消息
在状态栏中显⽰实时消息是通过 showMessage() 函数来实现,⽰例如下:
status->showMessage("Hello, world", 2000);
3. 在状态栏中显示永久消息
在状态栏中可以显⽰永久消息,此处的永久消息是通过 标签 来显示的;⽰例如下:
// 创建状态栏 QStatusBar* status = statusBar(); // 将状态栏置于窗口中 setStatusBar(status); // 创建标签 QLabel* label = new QLabel("提示消息", this); // 将标签放入状态栏中 status->addWidget(label);
调整显⽰消息的位置,将创建的标签放入到状态栏的右侧
// 将创建的标签放入到状态栏的右侧 QLabel* label2 = new QLabel("右侧提示消息", this); status->addPermanentWidget(label2);
四、浮动窗口
在 Qt 中,浮动窗⼝也称之为铆接部件。浮动窗⼝是通过 QDockWidget类 来实现浮动的功能。浮动窗口⼀般是位于核心部件的周围,可以有多个。
1. 浮动窗口的创建
浮动窗⼝的创建是通过 QDockWidget类 提供的构造⽅法 QDockWidget()函数 动态创建的;示例如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 浮动窗口 QDockWidget* dockWidget = new QDockWidget("浮动窗口", this); // 将浮动窗口置于当前窗口中 addDockWidget(Qt::BottomDockWidgetArea, dockWidget); }
2. 设置停靠的位置
浮动窗⼝是位于中⼼部件的周围。可以通过 QDockWidget类 中提供 setAllowedAreas() 函数设置其允许停靠的位置。其中可以设置允许停靠的位置有:
- Qt::LeftDockWidgetArea 停靠在左侧
- Qt::RightDockWidgetArea 停靠在右侧
- Qt::TopDockWidgetArea 停靠在顶部
- Qt::BottomDockWidgetArea 停靠在底部
- Qt::AllDockWidgetAreas 以上四个位置都可停靠
示例如下:设置浮动窗口只允许上下停靠
五、对话框
1. 对话框介绍
对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗⼝实现的功能组件可以设置在对话框中。对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的⽤⼾交互。Qt常用的内置对话框有:QFiledialog(⽂件对话框)、QColorDialog(颜⾊对话框)、QFontDialog(字体对话框)、QInputDialog (输⼊对话框)和 QMessageBox(消息框) 。
2. 对话框分类
对话框分为 模态对话框 和 ⾮模态对话框。
- 模态对话框
模态对话框指的是:显⽰后⽆法与⽗窗⼝进⾏交互,是⼀种阻塞式的对话框。使⽤ QDialog::exec() 函数调⽤。
模态对话框适⽤于必须依赖用户选择的场合,⽐如消息显⽰,⽂件选择,打印设置等。
示例:
(1)新建 Qt 项⽬,在 ui ⽂件中的菜单栏中设置两个菜单:“⽂件” 和 “编辑”,在 菜单 “⽂件” 下新建菜单项:“创建” 并将菜单项 “新建” 置于⼯具栏中 ; 如下图⽰:
(2)在 mainwindow.cpp ⽂件中实现:当点击 “新建” 时,弹出⼀个模态对话框;
说明:在菜单项中,点击菜单项时就会触发 triggered() 信号。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 当点击新建时,弹出一个模态对话框,在菜单项中,当点击之后就会触发 triggered 信号 connect(ui->action, &QAction::triggered, [=](){ QDialog dlg(this); dlg.resize(200, 100); dlg.exec(); }); }
- 非模态对话框
⾮模态对话框显⽰后独⽴存在,可以同时与⽗窗⼝进⾏交互,是⼀种⾮阻塞式对话框,使用 QDialog::show()函数调用。
⾮模态对话框⼀般在堆上创建,这是因为如果创建在栈上时,弹出的⾮模态对话框就会⼀闪⽽过。同时还需要设置 Qt:WA_DeleteOnClose 属性,⽬的是:当创建多个⾮模态对话框时(如打开了多个非模态窗⼝),为了避免内存泄漏要设置此属性。
⾮模态对话框适⽤于特殊功能设置的场合,⽐如查找操作,属性设置等。
示例:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 非模态对话框 connect(ui->action, &QAction::triggered, [=](){ // 为了防止一闪而过,创建在堆区 QDialog* dlg = new QDialog(this); dlg->resize(200, 100); // 当 dlg 无限创建时(即一直不断地打开关闭窗口),设置下面这个属性就可以在关闭非模态对话框时释放这个对象 dlg->setAttribute(Qt::WA_DeleteOnClose); dlg->show(); }); }
- 混合属性对话框
混合属性对话框同时具有模态对话框和⾮模态对话框的属性,对话框的⽣成和销毁具有⾮模态对话框属性,功能上具有模态对话框的属性。
使⽤ QDialog::setModal() 函数 可以创建混合特性的对话框。通常,创建对话框时需要指定对话框的⽗组件。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); // 混合属性对话框 connect(ui->action, &QAction::triggered, [=](){ QDialog* dialog = new QDialog(this); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setModal(true); dialog->resize(200, 100); dialog->show(); }); }
3. Qt 内置对话框
Qt 提供了多种可复⽤的对话框类型,即 Qt 标准对话框。Qt 标准对话框全部继承于 QDialog类。常用标准对话框如下:
- 消息对话框 QMessageBox
消息对话框是应⽤程序中最常⽤的界⾯元素。消息对话框主要⽤于为⽤⼾提⽰重要信息,强制用户进行选择操作。
QMessageBox类中定义了静态成员函数,可以直接调⽤创建不同⻛格的消息对话框,其中包括:
其对应的函数原型如下:
代码示例1:问题提⽰消息对话框
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { resize(800, 600); QPushButton* btn = new QPushButton("消息对话框", this); QMessageBox* msg = new QMessageBox(this); msg->setWindowTitle("Warning Message"); // 设置消息对话框标题 msg->setText("Error Message!"); // 设置消息对话框内容 msg->setIcon(QMessageBox::Question); // 设置消息对话框类型 msg->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); // 在消息对话框上设置按钮 connect(btn, &QPushButton::clicked, [=](){ msg->show(); }); }
其中可以设置的按钮的类型如下:
- 颜色对话框 QColorDialog
颜⾊对话框的功能是允许⽤⼾选择颜⾊。继承⾃ QDialog 类。
常⽤⽅法介绍:
QColorDialog (QWidget *parent = nullptr) //创建对象的同时设置⽗对象 QColorDialog(const QColor &initial, QWidget *parent = nullptr) //创建对象的同时通过 QColor 对象设置默认颜⾊和⽗对象 void setCurrentColor(const QColor &color) //设置当前颜⾊对话框 QColor currentColor() const //获取当前颜⾊对话框 QColor getColor(const QColor &initial = Qt::white \ QWidget *parent = nullptr \ const QString& title = QString() \ QColorDialog::ColorDialogOptions options = ColorDialogOptions()) //打开颜色选择对话框,并返回⼀个QColor对象 // initial:设置默认颜⾊ // parent:设置⽗对象 // title:设置对话框标题 // options:设置选项 void open(QObject *receiver, const char *member) //打开颜⾊对话框
示例代码1:
#include "mainwindow.h" #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { resize(800, 600); QPushButton* btn = new QPushButton("颜色对话框", this); // 创建颜色对话框 QColorDialog* cdlg = new QColorDialog(this); connect(btn, &QPushButton::clicked, [=](){ // 打开颜色对话框, 并设置默认颜色为红色 QColor color = cdlg->getColor(QColor(255, 0, 0)); qDebug()
-
- 使⽤ QFileDialog 来实现选择⽂件的效果.
-