目录
[新建 Qt 项目](#新建 Qt 项目)
[5.4.2:颜色对话框 QColorDialog](#5.4.2:颜色对话框 QColorDialog)
[5.4.3:文件对话框 QFileDialog](#5.4.3:文件对话框 QFileDialog)
[5.4.4:字体对话框 QFontDialog](#5.4.4:字体对话框 QFontDialog)
Qt窗口是通过QMainWindow类来实现的
QMainWindow 是⼀个为用户提供主窗口程序的类,继承自QWidget 类,并且提供了⼀个预定义的布局。QMainWindow 包含一个菜单栏(menu bar) 、多个工具栏(tool bars) 、多个浮动窗口(铆接部件)(dock widgets) 、⼀个状态栏(status bar) 和**⼀个中心部件(central widget)**,它是许多应用程序的基础,如文本编辑器,图片编辑器等。如下图为 QMainwindow中各组件所处的位置.


1:菜单栏
Qt中的菜单栏 是通过QMenuBar 这个类来实现的,一个主窗口最多只有一个菜单栏.位于主窗口顶部、主窗口标题栏下面.
菜单栏中包含菜单. 菜单中包含菜单项.

1.1:创建菜单栏
方式一: 菜单栏的创建可以借助于 QMainWindow类 提供的 menuBar() 函数来实现。menubar()函数原型如下:

⽅式⼆:在堆上动态创建.

1.2:在菜单栏红添加菜单
创建菜单,并通过 QMenu 提供的 addMenu() 函数 来添加菜单。

1.3:创建菜单项
在 Qt 中,并没有专门的菜单项类,可以通过 QAction 类,抽象出公共的动作。如在菜单中添加菜单项.
- QAction 可以给菜单栏使用, 也可以给工具栏使用.

1.4:在菜单项之间添加分割线
在菜单项之间可以添加分割线。分割线如下图所示,添加分割线是通过 QMenu 类 提供的
addSeparator() 函数来实现.
代码示例1
在窗口上创建⼀个菜单栏,在菜单栏中添加⼀些菜单,在某⼀个菜单中添加⼀些菜单项。
新建 Qt 项目
注意:此时新建项目时选择的基类 QMainwindow ,如下图示:

在 "mainwindow.cpp" 文件中创建菜单和中央控件.
- 创建⼀个菜单栏, ⼀个菜单.
- 五个菜单项: 新建,打开,保存,另存为,退出.
- 创建⼀个 QTextEdit 作为窗口的中央控件.
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1. 先创建一个菜单栏
QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);
// 2. 创建菜单
QMenu* menu1 = new QMenu("文件");
QMenu* menu2 = new QMenu("编辑");
QMenu* menu3 = new QMenu("视图");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
// 3. 给菜单添加菜单项
QAction* action1 = new QAction("新建");
QAction* action2 = new QAction("打开");
QAction* action3 = new QAction("保存");
QAction* action4 = new QAction("另存为");
QAction* action5 = new QAction("退出");
menu1->addAction(action1);
menu1->addAction(action2);
menu1->addAction(action3);
menu1->addAction(action4);
menu1->addAction(action5);
// 4. 给 action 添加信号槽
//action1的triggered信号(即点击"新建" 菜单项)触发与之对应的槽函数
connect(action1, &QAction::triggered, this, &MainWindow::handle);
connect(action5, &QAction::triggered, this, &MainWindow::close);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle()
{
qDebug() << "触发新建操作!";
}

代码示例2
创建⼀个菜单栏, ⼀个菜单.
两个菜单项: 保存, 加载.
创建⼀个 QTextEdit 作为窗口的中央控件.
使用QFileDialog 来实现选择文件的效果.
getSaveFileName 用于保存文件的场景. 此时的对话框可以输入问津名.
getOpenFileName 用于打开文件的场景. 此时的对话框可以获取到鼠标选择的⽂件名.
搭配 C++ 标准库的文件操作实现文件读写.
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QTextEdit>
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
void save();
void load();
~MainWindow();
private:
Ui::MainWindow *ui;
QTextEdit *edit; // 改为类的成员变量
};
#endif // MAINWINDOW_H
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextEdit>
#include <QFileDialog>
#include <fstream>
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 = new QTextEdit(this);
this->setCentralWidget(edit);
edit->setPlaceholderText("此处编写文本内容.....");
connect(action1,&QAction::triggered,this,&MainWindow::save);
connect(action2,&QAction::triggered,this,&MainWindow::load);
}
void MainWindow::save()
{
//弹出对话框,选择写入文件的路径
QFileDialog * dialog = new QFileDialog(this);
QString fileName = dialog->getSaveFileName(this,"保存文件","D:/Test");
qDebug() <<"fileName:>" << fileName;
std::ofstream file(fileName.toStdString().c_str());
if(!file.is_open())
{
qDebug() <<"文件保存失败";
return;
}
const QString & text = edit->toPlainText();
file << text.toStdString();
file.close();
}
void MainWindow::load()
{
QFileDialog * dialog = new QFileDialog(this);
QString fileName = dialog->getOpenFileName(this,"加载文件","D:/Test");
qDebug()<<"fileName: "<<fileName;
//读取文件
std::ifstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
qDebug() << "⽂件加载失败!";
return;
}
std::string content;
std::string line;
while(std::getline(file,line))
{
content += line;
content += "\n";
}
file.close();
QString text = QString::fromStdString(content);
edit->setPlainText(text);
}
MainWindow::~MainWindow()
{
delete ui;
}


代码示例3
给菜单设置快捷键
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar * menuBar = new QMenuBar();
this->setMenuBar(menuBar);
//创建菜单
QMenu* menu1 = new QMenu("文件 (&F)");
QMenu* menu2 = new QMenu("编辑 (&E)");
QMenu* menu3 = new QMenu("视图 (&V)");
QMenu* menu4 = new QMenu("关于 (&A)");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
menuBar->addMenu(menu3);
menuBar->addMenu(menu4);
//创建菜单项
QAction* action1 = new QAction("菜单项1");
QAction* action2 = new QAction("菜单项2");
QAction* action3 = new QAction("菜单项3");
QAction* action4 = new QAction("菜单项4");
menu1->addAction(action1);
menu2->addAction(action2);
menu3->addAction(action3);
menu4->addAction(action4);
}
MainWindow::~MainWindow()
{
delete ui;
}


代码示例4
cpp
#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("文件(&F)");
QMenu* menu2 = new QMenu("视图(&V)");
menuBar->addMenu(menu1);
menuBar->addMenu(menu2);
//创建四个菜单项
QAction* action1 = new QAction("action1 (&Q)");
QAction* action2 = new QAction("action2 (&W)");
QAction* action3 = new QAction("action3 (&E)");
QAction* action4 = new QAction("action4 (&R)");
menu1->addAction(action1);
menu1->addAction(action2);
menu2->addAction(action3);
menu2->addAction(action4);
//不绑定槽函数, 通过快捷键选中也没啥反应~
connect(action1,&QAction::triggered,this,&MainWindow::handle1);
connect(action2,&QAction::triggered,this,&MainWindow::handle2);
connect(action3,&QAction::triggered,this,&MainWindow::handle3);
connect(action4,&QAction::triggered,this,&MainWindow::handle4);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle1()
{
qDebug() <<"handle1";
}
void MainWindow::handle2()
{
qDebug() <<"handle2";
}
void MainWindow::handle3()
{
qDebug() <<"handle3";
}
void MainWindow::handle4()
{
qDebug() <<"handle4";
}



代码示例5
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar * menuBar = new QMenuBar();
this->setMenuBar(menuBar);
QMenu * menuParent = new QMenu("父菜单");
QMenu * menuChild = new QMenu("子菜单");
menuBar->addMenu(menuParent);
menuParent->addMenu(menuChild);
QAction * action1 = new QAction("菜单项1");
QAction * action2 = new QAction("菜单项2");
menuChild->addAction(action1);
menuChild->addAction(action2);
QMenu * menuChild2 = new QMenu("子菜单2");
menuChild->addMenu(menuChild2);
}
MainWindow::~MainWindow()
{
delete ui;
}


代码示例6
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar * menuBar = new QMenuBar();
this->setMenuBar(menuBar);
QMenu * menu = new QMenu("菜单");
menuBar->addMenu(menu);
QAction * action1 = new QAction("菜单项1");
QAction * action2 = new QAction("菜单项2");
menu->addAction(action1);
//添加分割线
menu->addSeparator();
menu->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}


代码示例7
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QMenuBar * menuBar = this->menuBar();
this->setMenuBar(menuBar);
QMenu * menu = new QMenu("菜单");
menu->setIcon(QIcon(":/Directory.png"));
menuBar->addMenu(menu);
QAction* action1 = new QAction("open");
action1->setIcon(QIcon(":/Directory.png"));
QAction* action2 = new QAction("save");
action2->setIcon(QIcon(":/save.png"));
menu->addAction(action1);
menu->addAction(action2);
}
MainWindow::~MainWindow()
{
delete ui;
}


1.5:关于QMenuBar的创建方式的讨论
cpp
QMenuBar * menuBar = new QMenuBar();
this->setMenuBar(menuBar);
- 如果我们创建项目,没有勾选自动生成ui文件,此时上述代码是ok的.
- 如果勾选了自动生成ui文件(Qt已经给生成了一个QMenuBar),上述代码则会引起内存泄露.


2:工具栏
工具栏是应用程序中集成各种功能实现快捷键使用的⼀个区域。可以有多个,也可以没有,它并不是应用程序中必须存在的组件。它是⼀个可移动的组件,它的元素可以是各种窗口组件,它的元素通常以图标按钮的方式存在。如下图为工具栏的示意图:

2.1:创建工具栏
调用QMainWindow类 的 addToolBar() 函数来创建工具栏,每增加⼀个工具栏都需要调用一次该函数。
如添加两个⼯具栏.

2.2:设置停靠位置
⼯具栏停靠位置的设置有两种方式。⼀种是在创建工具栏的同时指定停靠的位置,另⼀种是通过QToolBar类 提供的 setAllowedAreas()函数来设置。
2.2.1:方式一
在创建工具栏的同时,也可以设置工具栏的位置,其默认位置是在窗口的最上面;如上述代码,默认在最上面显示。工具栏允许停靠的区域由QToolBar类 提供的**allowAreas()**函数 决定,其中可以设置的位置包括:
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠

2.2.2:方式二
使用QToolBar类提供的 setAllowedAreas()函数 设置停靠位置

在创建工具栏的同时指定其停靠的位置,指的是程序运行时工具栏默认所在的位置;而使用setAllowedAreas()函数设置停靠位置,指的是工具栏允许其所能停靠的位置.
2.3:设置浮动属性
⼯具栏的浮动属性可以通过 QToolBar类 提供的 setFloatable() 函数 来设置。setFloatable()函数原型为:
void setFloatable ( bool floatable ).
- true:浮动
- false:不浮

2.4:设置移动属性
设置工具栏的移动属性可以通过 QToolBar类 提供的 setMovable() 函数 来设置 setMovable()函数.
void setMovable (bool movable)
true:移动.
false:不移动.
说明:若设置工具为不移动状态,则设置其停靠位置的操作就不会生效,所以设置工具栏的移动属性类似于总开关的效果.
2.5:代码示例1
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void handle1();
void handle2();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建菜单栏
QMenuBar * menuBar = this->menuBar();
this->setMenuBar(menuBar);
//创建菜单
QMenu * menu = new QMenu("文件");
menuBar->addMenu(menu);
//工具栏是需要手动创建出来的,自身不会自动创建
QToolBar* toolBar = new QToolBar();
this->addToolBar(toolBar);
//创建两个菜单栏
QAction* action1 = new QAction("保存");
QAction* action2 = new QAction("打开");
action1->setIcon(QIcon(":/Directory.png"));
action2->setIcon(QIcon(":/save.png"));
//将菜单项放到菜单中
menu->addAction(action1);
menu->addAction(action2);
connect(action1,&QAction::triggered,this,&MainWindow::handle1);
connect(action2,&QAction::triggered,this,&MainWindow::handle2);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handle1()
{
qDebug() << "handle1";
}
void MainWindow::handle2()
{
qDebug() << "handle2";
}


2.6:代码示例2
mainwindow.cpp
- Qt::LeftToolBarArea 停靠在左侧
- Qt::RightToolBarArea 停靠在右侧
- Qt::TopToolBarArea 停靠在顶部
- Qt::BottomToolBarArea 停靠在底部
- Qt::AllToolBarAreas 以上四个位置都可停靠
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QToolBar * toolBar1 = new QToolBar();
QToolBar * toolBar2 = new QToolBar();
this->addToolBar(toolBar1);
//Qt::LeftToolBarArea停靠在左侧
this->addToolBar(Qt::LeftToolBarArea,toolBar2);
//只允许停靠在左侧或右侧
toolBar2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置不允许浮动
toolBar2->setFloatable(false);
//设置不允许移动
toolBar2->setMovable(false);
QAction* action1 = new QAction("动作1");
QAction* action2 = new QAction("动作2");
QAction* action3 = new QAction("动作3");
QAction* action4 = new QAction("动作4");
toolBar1->addAction(action1);
toolBar1->addAction(action2);
toolBar2->addAction(action3);
toolBar2->addAction(action4);
}
MainWindow::~MainWindow()
{
delete ui;
}

3:状态栏
状态栏是应用程序中输出简要信息的区域. 一般位于主窗口的最底部,一个窗口最多只能有一个状态栏.在Qt中,状态栏中通过QStatusBar类来实现的.在状态栏中可以显示的消息类型有:
- 实时消息:如当前程序状态.
- 永久消息:如程序版本号,机构名称.
- 进度消息:如进度条提示,百分百提示.
3.1:状态栏的创建
状态栏的创建是通过 QMainWindow 类 提供的 **statusBar()**函数来创建;示例如下:

3.2:在状态栏中显示实时消息
在状态栏中显示实时消息是通过showMessage() 函数来实现,示例如下:

3.3:在状态栏显示永久消息
在状态栏中可以显示永久消息,此处的永久消息是通过 标签 来显示的;示例如下:




代码示例
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QProgressBar>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//存在就获取,不存在就创建
QStatusBar * statusBar = this->statusBar();
// 如果状态栏没有被创建, 这样的设置是必要的.
// 如果状态栏已经在窗口中存在,这样的设置其实意义不大,但是也没副作用,仍然保留.
this->setStatusBar(statusBar);
// //显示一个临时的信息.
// statusBar->showMessage("这是一个状态消息");
//给状态栏中添加子控件
QLabel * label = new QLabel("这是一个QLabel");
statusBar->addWidget(label);
QProgressBar * progressBar = new QProgressBar();
progressBar->setRange(0,100);
progressBar->setValue(50);
statusBar->addWidget(progressBar);
QPushButton * button = new QPushButton("按钮");
//使用 addPermanentWidget 将这个按钮添加到状态栏的右端.与常规的addWidget不同,addPermanentWidget会将控件固定在状态栏的最右侧,且不随状态栏中的其他控件变化而移动.
statusBar->addPermanentWidget(button);
}
MainWindow::~MainWindow()
{
delete ui;
}


4:浮动窗口
在 Qt 中,浮动窗口也称之为铆接部件。浮动窗⼝是通过QDockWidget 类 来实现浮动的功能。浮动窗口⼀般是位于核心部件的周围,可以有多个。
4.1:浮动窗口的创建
浮动窗口的创建是通过 QDockWidget类 提供的构造方法 QDockWidget()函数 动态创建的;示例如下:

4.2:设置停靠的位置
浮动窗口是位于中心部件的周围 。可以通过 QDockWidget类 中提供 setAllowedAreas() 函数设置其允许停靠的位置。其中可以设置允许停靠的位置有:
- Qt::LeftDockWidgetArea 停靠在左侧.
- Qt::RightDockWidgetArea 停靠在右侧.
- Qt::TopDockWidgetArea 停靠在顶部.
- Qt::BottomDockWidgetArea 停靠在底部.
- Qt::AllDockWidgetAreas 以上四个位置都可停靠.
示例如下:设置浮动窗口只允许上下停靠

代码示例
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDockWidget>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//给主窗口添加一个子窗口
QDockWidget * dockWidget = new QDockWidget();
//使用addDockWidget方法,把浮动窗口加入到子窗口中.
this->addDockWidget(Qt::LeftDockWidgetArea,dockWidget);
//浮动窗口也是可以设置标题的
dockWidget->setWindowTitle("这是浮动窗口");
// 给浮动窗口内部, 添加一些其他的控件.
// 不能直接给这个浮动窗口添加子控件, 而是需要创建出一个单独的 QWidget, 把要添加的控件加入到 QWidget 中.
// 然后再把这个 QWidget 设置到 dockWidget 中.
QWidget * container = new QWidget();
dockWidget->setWidget(container);
//创建布局管理器,把布局管理器设置到QWidget中
QVBoxLayout * layout = new QVBoxLayout;
container->setLayout(layout);
// 创建其他控件添加到 layout 中.
QLabel * label = new QLabel("这是一个QLabel");
QPushButton* button = new QPushButton("这是按钮");
layout->addWidget(label);
layout->addWidget(button);
//设置浮动窗口允许停靠的位置
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::TopDockWidgetArea);
}
MainWindow::~MainWindow()
{
delete ui;
}


5:对话框
5.1:对话框介绍
对话框是 GUI 程序中不可或缺的组成部分。⼀些不适合在主窗口实现的功能组件可以设置在对话框中。对话框通常是⼀个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。Qt常用的内置对话框有:QFiledialog(文件对话框)、QColorDialog(颜色对话框)、QFontDialog(字体对话框)、QInputDialog (输入对话框)和 QMessageBox(消息框) 。

代码示例1
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog *dialog = new QDialog(this);
dialog->setWindowTitle("对话框的标题");
//设置对话框的尺寸
dialog->resize(400,300);
//通过show方法显示出对话框
dialog->show();
//delete dialog;
}
MainWindow::~MainWindow()
{
delete ui;
}

- 不同于界面上的其他控件,Qt中的QDialog每次按下按钮,都会创建一个新的QDialog对象,并进行显示,每次点击都会创建新的对话框对象.
- 一个程序在运行过程中,可以无数次点击这个按钮,进一步的就产生出无数个这样的对象了,如果没有释放的话,那么就会导致内存泄漏.
- 我们直接delete dialog的话,一运行程序,对话框会一闪而过.

- 正确做法应该是把 delete 和关闭按钮的点击信号关联起来.
- 在用户点击关闭的时候, 触发 delete.
- Qt 为了让咱们写的方便, 直接给 QDialog 设置了一个属性, 可以通过设置属性, 完成上述效果.
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog *dialog = new QDialog(this);
dialog->setWindowTitle("对话框的标题");
//设置对话框的尺寸
dialog->resize(400,300);
//通过show方法显示出对话框
dialog->show();
//delete dialog;
dialog->setAttribute(Qt::WA_DeleteOnClose);
}
MainWindow::~MainWindow()
{
delete ui;
}

5.2:自定义对话框
要想自定义对话框,就需要继承自QDialog创建类.
- 通过纯代码的方式来自定义QDialog界面.
- 通过图形化的方式.
5.2.1:代码示例1(纯代码方式)
dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget * parent);
void handle();
};
#endif // DIALOG_H
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
dialog.cpp
cpp
#include "dialog.h"
#include <QDialog>
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>
Dialog::Dialog(QWidget * parent) : QDialog(parent)
{
//创建出一些控件,加入到Dialog中.(以Dialog作为父窗口)
QVBoxLayout * Layout = new QVBoxLayout();
this->setLayout(Layout);
QLabel * label = new QLabel("这是一个对话框",this);
QPushButton * button = new QPushButton("关闭",this);
Layout->addWidget(label);
Layout->addWidget(button);
connect(button,&QPushButton::clicked,this,&Dialog::handle);
}
void Dialog::handle()
{
this->close();
}
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
Dialog * dialog = new Dialog(this);
dialog->resize(400,300);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}


5.2.2:代码示例2(图形化界面方式)



dialog.h
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
mainwindow.h
cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
dialog.cpp
cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
this->close();
}
mainwindow.cpp
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <dialog.h>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
//弹出一个自定义的对话框
Dialog * dialog = new Dialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->exec();
}
5.3:对话框的分类
5.3.1:模态对话框
模态对话框指的是:显示后无法与父窗口进行交互,是⼀种阻塞式的对话框。简单来讲就是弹出对话框的时候,此时用户无法操作父窗口.必须得完成对话框内部出的操作,关闭对话框的时候,使用QDialog::exec() 函数调用.模态对话框适⽤于必须依赖用户选择的场合,比如消息显示,文件选择,打印设置等。
示例
1、新建 Qt 项目,在 ui 文件中的菜单栏中设置两个菜单:"文件" 和 "编辑",在 菜单 "文件" 下新建
菜单项:"创建" 并将菜单项 "新建" 置于工具栏中;如下图所示

2、在 mainwindow.cpp文件中实现:当点击 "新建" 时,弹出⼀个模态对话框;
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionxinjian,&QAction::triggered,[=]()
{
QDialog dlg(this);
dlg.resize(200,100);
dlg.exec();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
5.3.2:非模态对话框
非模态对话框显示后独立存在,可以同时与父窗口进行交互,是⼀种非阻塞式对话框,使用
QDialog::show()函数调用.
非模态对话框⼀般在堆上创建,这是因为如果创建在栈上时,弹出的非模态对话框就会⼀闪而过。同时还需要设置 Qt:WA_DeleteOnClose 属性,目的是:当创建多个非模态对话框时(如打开了多个非模态窗口)为了避免内存泄漏要设置此属性.
非模态对话框适用于特殊功能设置的场合,比如查找操作,属性设置等。
示例
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionxinjian,&QAction::triggered,[=]()
{
//非模态对话框,为了防止一闪而过,创建在堆区
QDialog * dlg = new QDialog(this);
//调整非模态对话框尺寸
dlg->resize(200,100);
/*当dlg2无线创建时(即一直不断地打开关闭窗口),设置下面这个属性就可以在关闭
非模态对话框时释放这个对象*/
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}

5.3.3:混合属性对话框
混合属性对话框同时具有模态对话框和非模态对话框的属性,对话框的生成和销毁具有非模态对话框属性,功能上具有模态对话框的属性。
使用QDialog::setModal()函数可以创建混合特性的对话框。通常,创建对话框时需要指定对话框的父组件。
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionxinjian,&QAction::triggered,[=]()
{
QDialog * dialog = new QDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModal(true);
dialog->resize(200,100);
dialog->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}

5.4:Qt内置对话框
Qt 提供了多种可复用的对话框类型,即 Qt 标准对话框 。Qt 标准对话框全部继承于QDialog类。常用标准对话框如下:
5.4.1:消息对话框QMessageBox
消息对话框是应⽤程序中最常用的界面元素。消息对话框主要用于为用户提示重要信息,强制用户进行选择操作.QMessageBox类中定义了静态成员函数,可以直接调用创建不同风格的消息对话框,其中包括:


其对应的函数原型如下:

5.4.1.1:问题提示对话框
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button1 = new QPushButton("消息对话框",this);
QMessageBox * Message = new QMessageBox(this);
//设置消息对话框的标题
Message->setWindowTitle("Warning Message");
//设置消息对话的内容
Message->setText("Error Message!");
//设置消息对话类型
Message->setIcon(QMessageBox::Question);
//在消息对话框上设置按钮
Message->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
connect(Button1,&QPushButton::clicked,[=]()
{
Message->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
实现效果如下.

其中可以设置的按钮的类型如下.

更改消息对话框中的按钮类型.
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button1 = new QPushButton("消息对话框",this);
QMessageBox * Message = new QMessageBox(this);
//设置消息对话框的标题
Message->setWindowTitle("Warning Message");
//设置消息对话的内容
Message->setText("Error Message!");
//设置消息对话类型
Message->setIcon(QMessageBox::Question);
//在消息对话框上设置按钮
Message->setStandardButtons(QMessageBox::Open | QMessageBox::Close);
connect(Button1,&QPushButton::clicked,[=]()
{
Message->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
实现效果如下

5.4.1.2:消息提示对话框
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("消息对话框",this);
QMessageBox * Message = new QMessageBox(this);
//设置消息对话框的标题
Message->setWindowTitle("Warning Message");
//设置消息对话框的内容
Message->setText("Error Message");
//设置消息对话框的类型
Message->setIcon(QMessageBox::Information);
//在消息对话框上设置按钮
Message->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
connect(Button,&QPushButton::clicked,[=]()
{
Message->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
实现效果如下.

5.4.1.3:警告信息消息对话框
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("消息对话框",this);
QMessageBox * Message = new QMessageBox(this);
//设置消息对话框的标题
Message->setWindowTitle("Warning Message");
//设置消息对话框的内容
Message->setText("Error Message");
//设置消息对话框的类型
Message->setIcon(QMessageBox::Warning);
//在消息对话框上设置按钮
Message->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
connect(Button,&QPushButton::clicked,[=]()
{
Message->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
实现效果如下

5.4.1.4:错误提示消息对话框
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("消息对话框",this);
QMessageBox * Message = new QMessageBox(this);
//设置消息对话框的标题
Message->setWindowTitle("Warning Message");
//设置消息对话框的内容
Message->setText("Error Message");
//设置消息对话框的类型
Message->setIcon(QMessageBox::Critical);
//在消息对话框上设置按钮
Message->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
connect(Button,&QPushButton::clicked,[=]()
{
Message->show();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
实现效果如下.

5.4.2:颜色对话框 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对象.
- void open(QObject *receiver, const char *member) //打开颜⾊对话框
initial:设置默认颜色.
parent:设置父对象.
title:设置对话框标题.
options:设置选项.
代码示例1
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QColorDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("颜色对话框",this);
//创建颜色对话框
QColorDialog * ColorDialog = new QColorDialog(this);
connect(Button,&QPushButton::clicked,[=](){
QColor color = ColorDialog->getColor(QColor(255,0,0));
qDebug() << "red:> " << color.red();
qDebug() << "green:> " << color.green();
qDebug() << "blue:> " << color.blue();
});
}
MainWindow::~MainWindow()
{
delete ui;
}

代码示例2
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QColorDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("颜色对话框",this);
//创建颜色对话框
QColorDialog * ColorDialog = new QColorDialog(this);
connect(Button,&QPushButton::clicked,[=](){
//设置颜色对话框中的颜色
ColorDialog->setCurrentColor(QColor(200,100,190));
ColorDialog->open();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
效果如下.

5.4.3:文件对话框 QFileDialog
文件对话框用于应用程序中需要打开⼀个外部文件或需要将当前内容存储到指定的外部文件.
常用方法介绍
1.打开文件(一次只能打开一个文件).
QString getOpenFileName(QWidget * parent = nullptr,const QString &caption = QString(),const QString &dir = QString(),const QString &filter = QString(),QString *selectedFilter = nullptr,QFileDialog::Options options = Options())
2.打开多个文件(一次可以打开多个文件).
QStringList getOpenFileNames(QWidget * parent = nullptr,const QString &caption = QString(),const QString &dir = QString(),const QString &filter = QString(),QString * selectedFilter = nullptr,QFileDialog::Options options = Options().
3.保存文件
QString getSaveFileNames(QWidget * parent = nullptr,const QString &caption = QString(),const QString &dir = QString(),const QString &filter = QString(),QString * selectedFilter = nullptr,QFileDialog::Options options = Options().
参数说明:
- 参数1: parent 父亲
- 参数2: caption 对话框标题
- 参数3: dir 默认打开的路径
- 参数4: filter 文件过滤器
代码示例1
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFileDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("文件",this);
QFileDialog * FileDialog = new QFileDialog(this);
connect(Button,&QPushButton::clicked,[=](){
QString str = FileDialog->getOpenFileName(
this,//父亲
"文件",
"D:\\桌面\\image",//打开的路径
"*.png"//只保留.png格式文件
);
});
}
MainWindow::~MainWindow()
{
delete ui;
}

代码示例2
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFileDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPushButton * Button = new QPushButton("文件",this);
QFileDialog * FileDialog = new QFileDialog(this);
connect(Button,&QPushButton::clicked,[=](){
QString str = FileDialog->getSaveFileName(this,//父亲
"文件",
"D:\\桌面\\image",
"*.png"
);
qDebug() << str;
});
}
MainWindow::~MainWindow()
{
delete ui;
}

5.4.4:字体对话框 QFontDialog
Qt 中提供了预定义的字体对话框类 QFontDialog,用于提供选择字体的对话框部件。
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QFontDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("字体",this);
connect(Button,&QPushButton::clicked,[=]()
{
//由于getFont方法第一个参数为bool类型,所以有此定义
bool flag;
//使用QFontDialog类的静态方法getFont打开字体对话框并设置默认格式.
QFont font = QFontDialog::getFont(&flag,QFont("微软雅黑",36));
//将char *转换为QString的方法
qDebug() <<"字体:> " << font.family().toUtf8().data();
//获取字号
qDebug() <<"字号:> "<<font.pointSize();
//是否要加粗
qDebug() <<"是否加粗:> " << font.bold();
//字体是否倾斜
qDebug() <<"是否倾斜:> " << font.italic();
});
}
MainWindow::~MainWindow()
{
delete ui;
}


5.4.5:输入对话框QInputDialog
Qt 中提供了预定义的输⼊对话框类:QInputDialog,于进行临时数据输入的场合。
常用方法介绍
1、双精度浮点型输入数据对话框.
1.double getDouble (QWidget * parent,const QString &title,const QString &label,double value = 0,double min = -2147483647, double max = 2147483647,int decimals = 1,bool * ok = nullptr,Qt::WindowFlags flags = Qt::WindowFlags());
2、 整型输入数据对话框
2.int getInt (QWidget * parent,const QString &title,const QString &label,double value = 0,double min = -2147483647, double max = 2147483647,int decimals = 1,bool * ok = nullptr,Qt::WindowFlags flags = Qt::WindowFlags());
3、选择条目型输入数据框
3.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);
参数说明:
parent:父亲.
title:对话框标题.
label:对话框标签.
items:可供选择的条目.
代码示例1(浮点型数据输入对话框)
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QInputDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("输入框",this);
QInputDialog * Dialog = new QInputDialog(this);
connect(Button,&QPushButton::clicked,[=](){
double d = Dialog->getDouble(this,"输入框","浮点型");
qDebug() << "d = " << d;
});
}
MainWindow::~MainWindow()
{
delete ui;
}

代码示例2(整型数据输入对话框)
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QInputDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("输入框",this);
QInputDialog * Dialog = new QInputDialog(this);
connect(Button,&QPushButton::clicked,[=](){
int i = Dialog->getInt(this,"输入框","Int");
qDebug() << "i = " << i;
});
}
MainWindow::~MainWindow()
{
delete ui;
}


代码示例3(打开选择条目对话框)
cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QInputDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
resize(800,600);
QPushButton * Button = new QPushButton("输入框",this);
QInputDialog * Dialog = new QInputDialog(this);
connect(Button,&QPushButton::clicked,[=](){
QStringList items;
items << tr("Spring") << tr("Summer") << tr("Fall") << tr("Winter");
QString item = Dialog->getItem(this,"输入框","Item",items);
qDebug() <<"item: " << item.toUtf8().data();
});
}
MainWindow::~MainWindow()
{
delete ui;
}






