【QDialog】对话框
目录
一.见一见QDialog项目
二.简单示例
2.1.内存泄漏问题
三.自定义对话框
3.1.纯代码模式
3.2.通过图形化的方式
四.模态对话框和非模态对话框
五.Qt内置对话框
5.1.QMessageBox
5.1.1.简单示例
5.1.2.自定义按钮
5.1.3.通过exec的返回值知道按下了哪个内置按钮
5.1.4.通过内置静态函数来创建QMessageBox对话框
5.2.QColorDialog
5.3.QFileDialog
5.4.QFontDialog
5.5.QInputDialog
说时候,对话框其实是非常常见的。
就比如说下面这个对话框
在Qt中,使用QDialog类来表示对话框。
对话框是GUI程序中不可或缺的组成部分。
⼀些不适合在主窗⼝实现的功能组件可以设置在对话框 中。
对话框通常是⼀个顶层窗⼝,出现在程序最上层,⽤于实现短期任务或者简洁的⽤⼾交互。
Qt常 ⽤的内置对话框有:QFiledialog(⽂件对话框)、QColorDialog(颜⾊对话框)、QFontDialog (字体对话框)、QInputDialog(输⼊对话框)和QMessageBox(消息框)。
一.见一见QDialog项目
我们在之前都是以QWidget或者QMainWindow作为基类来创建项目的
那么在这里,我就来以QDialog作为基类来创建我们的项目
创建好项目之后,我们看看里面的文件
其实和QWidget,QMainWindow的项目差不多了太多。只不过是换成了QDialog而已。
我们去看看.ui文件
右边
看起来还是和它们差不多。
我们运行一下程序
我们注意一下右上角
这个和QWidget,QMainWindow项目的可是有区别的。
总体来说,基于 QDialog 作为父类创建出来的程序窗口和之前通过 QWidget ,QMainWindow创建出来的非常相似的。
我们可以去.ui文件右边看看继承关系
我们发现这个QDialog是继承自这个QWidget的!!!
实际开发中,更多的情况,往往不是直接在创建项目的时候继承自 QDialog,而是在代码中,创建额外的类,让额外的类继承自 QDialog
主窗口,一般不会作为一个对话框!
主窗口可以再产生出一些其他的对话框~~
二.简单示例
在这个例子中,我们通过点击按钮,弹出一个对话框。
我们先创建一个项目
注意我们这个项目是以QMainWindow作为基类的。
实际开发中,更多的情况,往往不是直接在创建项目的时候继承自 QDialog,而是在代码中,创建额外的类,让额外的类继承自 QDialog
我们直运行一下
点击这个按钮一下
我们发现就弹出了一个对话框,如果说你觉得太小了,那么我们可以设置一下
这样子我们按下按钮弹出的对话框的大小就比较好看了啊。
我们发现这个对话框还有一个标题。其实这个标题也是可以设置的
大家不要忘了QDialog是继承自QWidget,那么我们的QDialog可以使用QWidget的所有属性和方法。
2.1.内存泄漏问题
但是大家不要忘了,这里有一个问题,如果我们点击多次按钮,就会创建多个对话框
每一个对话框都是一个单独的Dialog对象。
此处每次按下按钮,都会通过 new
操作在堆上创建一个新的 QDialog
对象并显示出来。也就是说,每次点击按钮,都会生成一个全新的对话框。
但是谁来delete呢?
有的人说,我们点击下面这个X不就会自动delete了吗?
事实上呢!
如果我们不做任何设置的话,在这种情况下,点击对话框上的叉关闭窗口时,不会自动删除 dialog
对象!
-
点击对话框右上角的关闭按钮(叉)时,Qt 默认会调用
QDialog::close()
方法 -
close()
方法会隐藏对话框,但不会自动删除 QDialog 对象 -
对话框对象仍然存在于内存中,只是不可见了
这会导致一个潜在的问题:如果用户反复点击按钮,程序中就会不断累积 QDialog
对象,从而造成大量的内存占用。
极端情况下,如果无限次点击,就会在内存中创建无数个对话框对象,进而引发内存泄漏,严重影响程序性能甚至导致程序崩溃。
有的人说,不是说父类会管理子类的资源释放吗?
尽管在代码中,我们将 QDialog
的父对象设置为 this
(即主窗口QMainWindow),这样当主窗口QMainWindow被销毁时,所有关联的对话框也会被一并销毁,从而避免最严重的内存泄漏。
但是,万一我的主窗口QMainWindow没有这么快就被销毁呢?在这个期间如果创建大量的QDialog,那就不会造成大量的内存占用吗?
很显然,这并不能解决在主窗口QMainWindow存活期间,反复创建多个对话框QDialog所带来的内存资源浪费问题。
那么我们怎么解决呢?
有人说直接加一个delete即可
我们可以运行一下
我们发现我们按下按钮之后,生成了一个弹窗之后立马关闭了。
很显然这个是不行的。
我们还是得从下面这里入手
这里就涉及一个Dialog的属性
QDialog的Attribute 属性
在 Qt 中,Attribute 属性是 QWidget 及其子类(包括 QDialog)的一个重要特性,它们控制着窗口部件的行为、外观和状态管理。这些属性通过 setAttribute() 方法设置,通过 testAttribute() 方法检查。
以下是常用选项
Qt::WA_DeleteOnClose
作用:当窗口关闭时,自动删除该窗口对象(即调用delete操作符)。
详细说明:
-
这个属性是QWidget的一个属性,可以通过setAttribute(Qt::WA_DeleteOnClose)来设置。
-
设置后,当窗口关闭(即收到关闭事件)时,Qt会在内部调用deleteLater()来删除该对象,从而释放内存。
-
这个属性对于动态分配(在堆上创建)的窗口特别有用,因为如果不在关闭时删除,则必须由创建者来负责删除,否则会造成内存泄漏。
-
注意:绝对不能对栈上创建的窗口设置此属性,因为栈上的对象在作用域结束时会自动销毁,如果Qt再删除一次就会导致双重删除,引发程序崩溃。
-
另外,对于父对象(parent不为nullptr)的窗口,通常父对象删除时会同时删除子对象,所以即使不设置这个属性,也可能在父对象删除时被删除。但是,如果父对象不删除,而子窗口关闭时希望自动删除,则可以使用这个属性。
Qt::WA_QuitOnClose
作用:当窗口关闭时,退出应用程序。
详细说明:
-
这个属性通常用于主窗口。当设置了这个属性后,关闭这个窗口将会导致应用程序退出(即触发QApplication::quit())。
-
注意:这个属性一般只用于主窗口,因为对于非主窗口,关闭一个窗口就退出整个应用程序可能不是用户所期望的。
-
默认情况下,QApplication会在最后一个窗口关闭时退出,但如果你有多个窗口,并且你希望关闭某个特定窗口时退出,则可以设置这个属性。
Qt::WA_ShowModal
作用:将窗口设置为模态。
详细说明:
-
设置这个属性后,窗口会以模态方式运行,即它会阻塞同一应用程序中其他窗口的输入。
-
这个属性与QDialog::setModal(true)的效果相同,但QDialog默认就是模态的(除非使用Qt::NonModal)。
-
模态窗口通常用于必须由用户完成当前操作才能继续的场景,比如打开文件、设置参数等。
-
注意:模态窗口有自己的事件循环,它会阻止用户与父窗口交互,直到模态窗口被关闭。
Qt::WA_AlwaysShowToolTips
作用:即使窗口处于非活动状态,也显示工具提示(ToolTips)。
详细说明:
-
默认情况下,工具提示只在窗口活动(即具有焦点)时显示。设置这个属性后,即使窗口失去焦点,工具提示也会显示。
-
这个属性对于需要一直显示提示信息的场景很有用,比如在托盘图标或某些常驻窗口上。
-
注意:这个属性是针对整个窗口的,会影响到窗口内所有控件的工具提示行为。
Qt::WA_TranslucentBackground
作用:设置窗口背景为半透明。
详细说明:
-
这个属性会使窗口背景半透明,从而可以看到背后的内容。注意,这需要底层窗口系统的支持。
-
设置这个属性后,窗口背景可能会变成完全透明,因此你需要确保窗口内容(比如绘制一些图形或控件)能够正确显示。
-
通常,要实现半透明窗口,还需要设置窗口的样式表或者重写paintEvent来绘制背景。
-
注意:这个属性与Qt::WA_NoSystemBackground属性互斥,如果同时设置,则Qt::WA_TranslucentBackground优先。
我们直接修改代码即可
现在我们点击下面这个
就会自动delete这个Dialog对象了。
三.自定义对话框
要想自定义对话框, 就需要继承自 QDialog 创建类
那么怎么继承呢?其实是有两种方式的
- 纯代码的方式来自定义 QDialog 界面
- 通过图形化的方式
3.1.纯代码模式
我们创建一个新的项目
在这个例子中,我们通过点击按钮,弹出一个对话框。
我们先创建一个项目
注意我们这个项目是以QMainWindow作为基类的。
实际开发中,更多的情况,往往不是直接在创建项目的时候继承自 QDialog,而是在代码中,创建额外的类,让额外的类继承自 QDialog
这回我们不再是使用QDialog了,我们新建一个类
创建好了之后我们去看看
我们发现这个代码还是有点问题的,我们给他添加一个头文件QDialog
这样子就没有报错了。
接下来我们把这个dialog.h和dialog.cpp进行修改一下
现在我们就可以去我们的槽函数里面编写一下代码了
我们运行一下
点击对话框
现在这个弹窗里面还是什么都没有,不过没有关系,我们现在就去进行修改一下这个Dialog类的构造函数
为啥这样子可以呢?
其实这是因为Qt的父子关系机制还有一层含义:子类控件会显示在父类控件上
我们运行一下
怎么样?是不是都显示在这上面了,只不过有一点乱,我们加一个布局管理器,同时我们也给这个按钮设置了槽函数。
我们运行看看
点击这个按钮看看
点击关闭看看
大家仔细观察的话就会发现,这个和我们平时使用代码的情况不是一模一样的吗!!
只不过我们把父对象换成了我们自定义的类而已。
3.2.通过图形化的方式
接下来我们就通过我们的图形化的界面来实现我们的自定义对话框
我们创建一个新的项目
在这个例子中,我们通过点击按钮,弹出一个对话框。
我们先创建一个项目
注意我们这个项目是以QMainWindow作为基类的。
实际开发中,更多的情况,往往不是直接在创建项目的时候继承自 QDialog,而是在代码中,创建额外的类,让额外的类继承自 QDialog
这个时候我们就需要通过.ui文件来自定义我们的对话框了,这需要我们自己创建一个.ui文件
这个操作是创建.ui文件以及对应的类
创建好了之后我们的项目的结构就是下面这样子
我们发现新创建出来了对应的头文件,源文件,.ui文件。
我们可以看看里面的内容
我们发现这个.h和.cpp文件里面已经内置好了这个自定义.ui文件的相关类。
只要我们创建这个dialog对象,他就会去这个自定义.ui文件的相关类里面获取自定义.ui文件上面的控件的信息。
接下来我们去自定义.ui文件里面干点事
我们点进去,然后我们放一些控件上去
这个时候我们在右边可以看到
当然,这个时候我们可以给我们的关闭按钮设置槽函数
注意:跳转到dialog.cpp里面去了
这个时候我们回去mainwindow.cpp写我们最开始还没有写完的槽函数
我们运行一下
点击按钮
点击关闭按钮
就是这样子的!!!
四.模态对话框和非模态对话框
我们来详细、系统地讲解一下Qt中对话框的这2种模式:模态对话框、非模态对话框
1. 模态对话框
模态对话框是最严格、最具强制性的交互方式。
-
核心特性:阻塞
当一个模态对话框弹出后,它会阻塞其父窗口(以及整个应用程序中与父窗口在同一线程的窗口)的消息循环。用户必须首先处理这个对话框,在关闭它之前,无法与背后的父窗口进行任何交互。 -
调用方式:
exec()
使用QDialog::exec()
函数来启动对话框。这个函数会启动一个局部的事件循环,并一直等待,直到对话框被关闭(用户点击“确定”、“取消”或关闭按钮)。exec()
函数会返回一个结果码(如QDialog::Accepted
或QDialog::Rejected
),告诉你用户是如何关闭对话框的。 -
行为表现:
-
对话框始终位于父窗口之上。
-
父窗口的标题栏通常会变灰,视觉上提示其不可用状态。
-
用户除了回应对话框,没有其他选择。
-
-
适用场景:
-
关键决策:需要用户立即关注并做出重要决定的场合。例如:
-
“文件尚未保存,是否保存?”
-
输入登录密码。
-
确认一个不可逆的删除操作。
-
-
必要信息:必须提供某些信息才能继续下一步操作的场合。例如:打开文件时选择文件。
-
2. 非模态对话框
非模态对话框提供了更灵活、更并行的交互方式。
-
核心特性:非阻塞
当非模态对话框弹出后,它和父窗口是独立并存的。用户可以自由地在对话框和父窗口之间来回切换,同时与两者进行交互,互不影响。 -
调用方式:
show()
使用QDialog::show()
函数来显示对话框。这个函数会立即返回,不会阻塞代码的执行。程序的主事件循环同时管理着父窗口和这个对话框。 -
我们在上面写的所有代码都是非模态对话框,因为我们显示对话框的时候使用的是show()。
-
行为表现:
-
对话框像一个独立的工具窗口。
-
父窗口可以正常操作。
-
用户可以同时打开多个非模态对话框。
-
-
适用场景:
-
工具性设置:不紧急、可随时调整的功能。例如:
-
文本编辑器的“查找和替换”对话框。
-
绘图软件的“调色板”或“画笔属性”窗口。
-
IDE 的“项目属性”设置。
-
-
我们回到我们上面的例子啊
我们运行一下
我们点击按钮
这个时候我们点击主窗口,我们发现还是可以操作主窗口的
那么我们把这个程序修改成模态的对话框
我们运行一下
我们点击按钮
这个时候我们点击主窗口,却一直操作不了主窗口,反而这个子窗口一直在闪烁。
事实上呢,对于这个模态对话框,由于他是阻塞运行的,只要这个对话框被关闭了,才会继续往下面执行,那么对于内存释放的方式,其实是有2种选择的
除了设置下面这个Attribute属性:dialog->setAttribute(Qt::WA_DeleteOnClose);
其实它也可以直接在最后面进行delete
这个是完全没有问题的。
五.Qt内置对话框
Qt提供了多种可复⽤的对话框类型,即Qt标准对话框。
Qt标准对话框全部继承于QDialog类。
常⽤标准对话框如下:
5.1.QMessageBox
消息对话框是应⽤程序中最常⽤的界⾯元素。
消息对话框主要⽤于为⽤⼾提⽰重要信息,强制⽤⼾进 ⾏选择操作。
QMessageBox类中定义了静态成员函数,可以直接调⽤创建不同⻛格的消息对话框,其中包括:
5.1.1.简单示例
我们创建一个新项目,新项目的基类还是QMainWindow
我们来编写代码
注意:我这里给对话框设置的图标是Qt内置好的图标
它们的样式大概就和下面的差不多
注意:我们这里也使用了Qt内置的按钮,还有很多按钮还没有展示,下面这个是Qt内置的按钮源码
我们运行一下
点击按钮
我们发现上面就有3个按钮吧。
5.1.2.自定义按钮
我们把上面代码的内置按钮部分的代码删除了
我们运行一下
我们发现默认就有1个OK按钮啊!!
这里使用了一个函数啊
这个ButtonRole是啥意思啊?
我们直接把鼠标放到ButtonRole,然后点击F1。
额,我知道这样子不够直观,我们下面看看通俗易懂版本的介绍
1. InvalidRole(无效角色)
-
通俗解释:这个按钮“名不副实”,或者暂时没什么用。你通常不会主动使用它,它可能被系统内部用来处理一些特殊情况。
-
好比:一个坏了或者被遮住的按钮,按了也没反应。
2. AcceptRole(接受角色)
-
通俗解释:“好的,就这么办!” 这是最常用的“肯定”按钮。点击它意味着你同意对话框里的内容,并且要执行主要操作,然后对话框会关闭。
-
典型按钮:确定、打开、保存、是。
-
好比:店员问:“这份订单您确认了吗?” 你回答:“确认!”
3. RejectRole(拒绝角色)
-
通俗解释:“算了,当我没说。” 这是最常用的“否定”按钮。点击它意味着你不想继续当前操作,要取消一切,对话框也会关闭。按键盘上的
Esc
键通常也相当于点击了这个按钮。 -
典型按钮:取消、关闭。
-
好比:店员问:“这份订单您确认了吗?” 你回答:“不,我再看看。”
4. DestructiveRole(破坏性角色)
-
通俗解释:“我确定要干这件危险的事!” 这个按钮用来执行一个有破坏性、不可轻易撤销的操作,比如删除文件、清空数据。在 macOS 上,这类按钮通常会被设置成醒目的红色。
-
典型按钮:删除、永久丢弃、覆盖。
-
好比:系统问:“您确定要永久删除这个文件吗?此操作无法撤销。” 你点击“删除”。
5. ActionRole(动作角色)
-
通俗解释:“先做点什么事,但先别关窗口。” 点击它会在对话框内部执行一个操作,但不会关闭对话框。通常用于让你在同一个对话框里继续下一步操作。
-
典型按钮:浏览...、选择颜色...、查找。
-
好比:在保存文件时,你点击“新建文件夹”按钮,创建完文件夹后,对话框还在,让你继续操作。
6. HelpRole(帮助角色)
-
通俗解释:“我不懂,快帮帮我!” 点击它会弹出帮助文档或说明,告诉你当前这个对话框是干什么的。
-
典型按钮:帮助、?。
-
好比:在复杂的软件设置里,你看到一个不明白的选项,点击“?”按钮查看解释。
7. YesRole(“是”角色) & 8. NoRole(“否”角色)
-
通俗解释:这是一对专门用来回答 “是”或“否” 问题的兄弟。
-
YesRole:明确地回答 “是”。
-
NoRole:明确地回答 “否”。
-
-
典型按钮:是、否。
-
好比:系统问:“文件已修改,是否保存?” 你用“是”或“否”来回答。
-
注意:它们和
AcceptRole/RejectRole
很像,但更侧重于回答一个直接的是非题,而不是广义的“接受/拒绝”一个操作。
9. ApplyRole(应用角色)
-
通俗解释:“先把刚才改的设置生效,但我还要继续改。” 点击它会让已经做出的更改立即生效,但不关闭对话框。常见于设置界面。
-
典型按钮:应用。
-
好比:你在调音效,调好一个参数后点击“应用”,马上就能听到效果,然后可以继续调整其他参数,而不用退出设置窗口。
10. ResetRole(重置角色)
-
通俗解释:“搞乱了,重来!” 点击它会将对话框里所有选项恢复到你打开它时的初始状态(或者默认状态)。
-
典型按钮:重置、恢复默认值。
-
好比:你在一个复杂的表单里填了一堆东西,发现填错了,点击“重置”,所有内容都清空,回到最初的样子。
我们运行一下
然后我们可以给这个按钮配置槽函数来处理按下这个按钮的反应。
5.1.3.通过exec的返回值知道按下了哪个内置按钮
自定义按钮可以有槽函数,那我这里一堆Qt内置的按钮呢?
它们可不能自定义槽函数。
那咋办呢?
事实上,用户点击按钮使得这个窗口关闭之后,此时就能通过这个exec的返回值来知道用户点击的是哪个按钮。
事实上呢,我们按下哪个按钮,他就返回对应按钮所对应的整数值。
就比如说,我们按下了Ok按钮,让窗口进行了关闭,事实上返回值就应该是下面这个
我们直接编写代码
运行一下
点击ok啊
重新点开对话框
点击Save啊
重新点开对话框
点击Cancel啊
咋样?懂了吗!
5.1.4.通过内置静态函数来创建QMessageBox对话框
我们创建一个新项目,新项目的基类还是QMainWindow
我们来编写代码
这个函数
点击按钮
我们发现和我们之前创建的对话框其实是差不多的。
那我们怎么知道我们按下的是哪个按钮呢。
事实上,这个QMessageBox::warning会返回一个返回值,我们可以通过这个返回值来确认是哪个按钮被按下了。
我们运行一下
按下OK,弹窗被关闭了
按下Cancel,弹窗被关闭了
怎么样?现在这个创建对话框的方法是不是比上面简单的多了。
事实上呢,针对下面不同种类的QMessage对话框,也是有不同种函数的
它们的用法都是大差不差的,我们看看
还是很不错的。
5.2.QColorDialog
颜⾊对话框的功能是允许⽤⼾选择颜⾊。
继承⾃QDialog类。
颜⾊对话框如下图⽰:
简单示例
我们创建一个新项目,新项目的基类还是QMainWindow
我们来编写代码,按照上面QMessage的理解,我们可以会写成下面这样子的代码
我们点击运行
点击这个按钮
我们发现确实是可以弹出这个对话框的。
但是实际上,我们不会像上面那样子做。我们一般是使用下面这个函数来调用我们的颜色对话框
这是一个非常方便的函数,因为它用一个静态方法(无需创建对话框对象)就能快速调用颜色选择对话框并获取用户选择的颜色。
//打开颜色选择对话框,并返回一个QColor对象
QColor QColorDialog::getColor(const QColor &initial= Qt::white, QWidget *parent = nullptr, const QString&title=QString(),QColorDialog:ColorDialogOptionsoptions=ColorDialogOptions())
函数功能概述
这个函数的核心功能是:弹出一个模态的颜色选择对话框,用户可以在其中选择或自定义一种颜色。当用户点击“确定”或“取消”后,函数会返回一个 QColor
对象作为结果。
返回值
-
返回值类型:
QColor
-
详解:
-
如果用户点击了 “OK”(确定) 按钮,则返回用户选择的颜色。
-
如果用户点击了 “Cancel”(取消) 按钮,或者关闭了对话框窗口,则返回的
QColor
对象是无效的。 -
关键点:你必须检查返回的颜色是否有效,然后再使用它。可以通过
QColor::isValid()
方法来检查。
-
参数详解
让我们逐一分解它的四个参数:
1. const QColor &initial = Qt::white
-
作用:设置颜色选择对话框打开时,默认选中的颜色。
-
详解:
-
当对话框弹出时,它会自动将你提供的这个
initial
颜色设置为当前选中色。 -
这为用户提供了一个起点,如果用户想选择的颜色和这个默认色很接近,会非常方便。
-
默认值是
Qt::white
(白色)。如果你不传递这个参数,对话框打开时默认选中的就是白色。
-
-
示例:
-
getColor(Qt::red):对话框打开时,红色被选中。
-
getColor(QColor(255, 128, 0)):对话框打开时,显示为橙色。
-
2. QWidget *parent = nullptr
-
作用:设置这个颜色对话框的父窗口。
-
详解:
-
模态行为:设置了父窗口后,对话框会成为一个模态对话框,这意味着在关闭颜色对话框之前,用户将无法与父窗口进行交互。
-
窗口居中:对话框通常会相对于父窗口居中显示,使界面更规整。
-
生命周期管理:对话框的生命周期会受父窗口影响(虽然不是强制的,但良好的编程实践建议这样做)。
-
默认值是
nullptr
,表示没有父窗口,此时对话框将作为一个独立的窗口出现在屏幕上。
-
-
示例:
-
getColor(Qt::white, this)
:this
通常指向调用它的那个窗口部件(比如一个QMainWindow
),对话框会以该窗口为父对象。
-
3. const QString &title = QString()
-
作用:设置颜色对话框的窗口标题。
-
详解:
-
你可以通过这个参数来自定义对话框标题栏上显示的文字,使其功能描述更清晰。
-
默认值是一个空字符串
QString()
,在这种情况下,Qt 会使用一个本地化的默认标题(如 “Select Color”)。
-
-
示例:
-
getColor(Qt::white, nullptr, “请选择背景色”)
:对话框的标题会显示为“请选择背景色”。
-
4. QColorDialog::ColorDialogOptions options = QColorDialog::ColorDialogOptions()
-
作用:通过一系列选项来定制颜色对话框的行为和外观。
-
详解:
-
这是一个枚举类型
QColorDialog::ColorDialogOption
的集合,你可以使用|
运算符来组合多个选项。 -
默认值是空(即不设置任何特殊选项),使用标准对话框。
-
常用选项包括:
-
QColorDialog::ShowAlphaChannel
:在对话框中显示透明度(Alpha)通道的选择条。允许用户选择半透明或全透明的颜色。 -
QColorDialog::NoButtons
:不显示“OK”和“Cancel”按钮。这在你将对话框作为其他界面的一部分时非常有用,你需要自己提供确认和取消的逻辑。 -
QColorDialog::DontUseNativeDialog
:在大多数平台上,Qt 会尝试使用操作系统原生的颜色对话框。使用此选项可以强制使用 Qt 自己绘制的对话框。这可以保证你的应用程序在不同操作系统上拥有一致的界面和行为,有时原生对话框功能可能受限(比如不支持某些选项)。
-
-
好了,基于上面这个函数,我们来重新修改一下我们的代码
我们运行一下
我们发现一开始就选择了绿色。然后我们可以随意的在调色板里面选择颜色
这个时候我们点击OK按钮的话
弹窗会消失,同时打印出下面这个
这是一个用 ARGB 格式 描述的颜色值。我们来一步步拆解它的意思:
-
ARGB 是什么?
-
A - Alpha:代表颜色的不透明度。
-
R - Red:代表红色分量。
-
G - Green:代表绿色分量。
-
B - Blue:代表蓝色分量。
-
-
数值范围:
这里的数值是在 0 到 1 之间表示的。0
表示完全没有该颜色成分,1
表示该颜色成分达到最大值。有时你也会看到 0-255 的表示法(例如在Photoshop中),这里的 0-1 是它的归一化表示。 -
具体分析
QColor(ARGB 1, 0.768627, 0.564706, 1)
:-
A (Alpha):
1
-
这意味着颜色是完全不透明的。如果这个值是
0
,则表示完全透明。
-
-
R (Red):
0.768627
-
这是一个非常高的红色值(约等于 77% 的红色强度)。
-
-
G (Green):
0.564706
-
这是一个中等偏高的绿色值(约等于 56% 的绿色强度)。
-
-
B (Blue):
1
-
这是最大值蓝色(100% 的蓝色强度)。
-
-
好了,见了点击Ok的情况,也来看看点击Cancel的情况吧。
我们再次点出这个对话框来
我们随便点击一个颜色
如果我们点击Cancel按钮,那么弹窗会关闭。
同时打印了下面这个
通过调色对话框来设置背景色
我们运行一下
点击确认
还行吧!!
点击OK
事实上,上面那个代码其实很不好看,我们完全可以像下面这样子来写
这个的效果和上面那个是一模一样的。
5.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())
这个函数是Qt框架中QFileDialog类的一个静态函数,用于打开一个文件选择对话框,让用户选择一个文件。函数返回用户选择的文件的路径(以QString形式)。如果用户取消选择,则返回一个空QString。
下面我来详细解释每个参数:
-
parent:
-
类型:QWidget*
-
默认值:nullptr
-
说明:这个参数用于指定父窗口。通常,你可以传入一个指向当前窗口的指针(例如this)。这样,文件对话框就会成为当前窗口的子窗口,并模态显示(即阻塞父窗口)。如果传入nullptr,则文件对话框将作为一个独立的窗口。
-
-
caption:
-
类型:const QString &
-
默认值:QString(),即空字符串
-
说明:对话框的标题。你可以设置一个字符串作为文件选择对话框的标题。如果留空,则使用默认标题(通常是“打开文件”或根据系统语言而定)。
-
-
dir:
-
类型:const QString &
-
默认值:QString(),即空字符串
-
说明:初始目录。指定文件对话框打开时显示的目录。例如,你可以设置为主目录(QDir::homePath())或者当前目录(QDir::currentPath())。如果留空,则使用系统默认的目录。
-
-
filter:
-
类型:const QString &
-
默认值:QString(),即空字符串
-
说明:文件过滤器。用于限制对话框中显示的文件类型。过滤器由一组用分号隔开的描述和通配符组成,多个过滤器之间用两个分号隔开。例如:
"图片文件 (*.png .jpg);;文本文件 (.txt)"
这样就会有两个过滤器:一个显示png和jpg文件,另一个显示txt文件。用户可以在对话框底部选择不同的过滤器。
-
-
selectedFilter:
-
类型:QString *
-
默认值:nullptr
-
说明:这是一个输出参数,用于返回用户选择的过滤器。如果你传入一个非空的QString指针,函数返回时,这个指针所指向的字符串将被设置为用户选择的过滤器。例如,如果你提供了两个过滤器(如上例),用户选择了“文本文件 (.txt)”,那么selectedFilter指向的字符串就会变成"文本文件 (.txt)"。如果你不需要这个信息,可以传入nullptr。
-
-
options:
-
类型:QFileDialog::Options
-
默认值:Options(),即默认选项
-
说明:这是一个枚举值,用于控制对话框的行为。你可以通过按位或(|)组合多个选项。常见的选项有:
-
QFileDialog::DontUseNativeDialog: 不使用系统原生对话框,而使用Qt自带的对话框。
-
QFileDialog::ReadOnly: 以只读方式打开,不允许用户重命名或删除文件。
-
等等。具体可以参考Qt文档。
-
-
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 getSaveFileName(QWidget *parent = nullptr, const QString &caption = QString(), constQString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr,QFileDialog::Options options = Options())
函数概述
QFileDialog::getSaveFileName
是一个静态函数,用于弹出一个保存文件对话框,让用户选择一个路径和文件名来保存文件。它返回用户选择的文件路径(QString
类型),如果用户取消了操作,则返回一个空字符串。
参数详解
参数1: parent
-
类型:
QWidget *
-
默认值:
nullptr
-
作用: 指定这个对话框的父窗口。
-
详解:
-
设置父窗口后,对话框会模态地显示在父窗口之上,并确保对话框不会消失在父窗口后面。
-
当父窗口被销毁时,对话框也会自动销毁。
-
如果传入
nullptr
,对话框将作为一个独立的顶级窗口。
-
参数2: caption
-
类型:
const QString &
-
默认值:
QString()
(空字符串) -
作用: 设置文件对话框的标题栏文字。
参数3: dir
(重点讲解)
-
类型:
const QString &
-
默认值:
QString()
(空字符串) -
作用: 设置文件对话框打开时默认显示的目录。
参数4: filter
-
类型:
const QString &
-
默认值:
QString()
(空字符串) -
作用: 设置文件类型过滤器,限制对话框中只显示特定扩展名的文件。
参数5: selectedFilter
-
类型:
QString *
-
默认值:
nullptr
-
作用: 用于获取用户实际选择的过滤器。
参数6: options
-
类型:
QFileDialog::Options
-
默认值:
Options()
(默认选项) -
作用: 用于设置对话框的一些额外行为和外观。
-
详解:
-
这是一个枚举值的组合,常用选项有:
-
QFileDialog::DontUseNativeDialog
: 不使用操作系统的原生对话框,而是使用 Qt 自己绘制的对话框。这在需要更精细的UI控制或解决原生对话框bug时有用。 -
QFileDialog::ShowDirsOnly
: 对于选择目录的对话框有用,在保存文件对话框中不常用。
-
-
我们直接写代码来
我们创建一个新项目,新项目的基类还是QMainWindow
它们的objetcname如下
我们给他们配置槽函数
我们运行一下
点击打开文件
我们这里选择一个文件
然后直接给我打印了
"D:/Qt5.14/project/build-test18-Desktop_Qt_5_14_0_MinGW_64_bit-Debug/ui_mainwindow.h"
点击保存文件
这个还是很熟悉的吧。
我们得给保存的文件输入一个名字
然后就会打印这个
"D:/Qt5.14/project/build-test18-Desktop_Qt_5_14_0_MinGW_64_bit-Debug/aaa"
当然啊,我们这里的保存不是真正的保存,不是说我们点击了这个保存就真的保存了,它需要另外去实现那个保存逻辑。我们在这里先不讲我们的保存逻辑,我们等到后续的文件章节再来讲讲。
5.4.QFontDialog
Qt 中提供了预定义的字体对话框类QFontDialog,⽤于提供选择字体的对话框部件。
我们创建一个新项目,新项目的基类还是QMainWindow
我们来编写代码
这里涉及一个新的函数
QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent = nullptr, const QString &title = QString(), QFontDialog::FontDialogOptions options = FontDialogOptions())
这个函数是Qt框架中QFontDialog类的一个静态成员函数,用于执行一个模态的字体对话框,并返回用户选择的字体。
函数参数说明:
-
bool *ok
:一个指向bool类型的指针。如果用户点击了对话框的“OK”按钮,则该指针所指向的值为true;如果用户点击了“Cancel”按钮,则为false。如果不需要这个信息,可以传入nullptr。 -
const QFont &initial
:初始字体。对话框打开时,会默认显示这个字体。 -
QWidget *parent = nullptr
:父窗口指针。通常用于指定对话框的父窗口,默认为空。 -
const QString &title = QString()
:对话框的窗口标题。如果不指定,则使用默认标题。 -
QFontDialog::FontDialogOptions options = FontDialogOptions()
:字体对话框的选项,用于控制对话框的行为和外观。默认情况下没有额外选项。
函数工作方式:
-
当调用这个函数时,它会创建一个模态的字体对话框(模态对话框会阻塞父窗口,直到用户关闭对话框)。
-
对话框会显示在屏幕上,用户可以选择字体、字号、样式等。
-
如果用户点击“OK”按钮,函数返回用户选择的字体,并且如果
ok
参数不是nullptr,则将其指向的值设为true。 -
如果用户点击“Cancel”按钮,函数返回初始字体(即传入的
initial
参数),并且如果ok
参数不是nullptr,则将其指向的值设为false。
我们运行一下这个程序
点击一下
这里我们就可以设置字体的情况
点击ok
这个啥意思呢?
-
"方正舒体"
-
意思:字体的家族名称。
-
白话:你要用的字体叫“方正舒体”。这是一种中文书法字体,看起来比较舒展、艺术。如果你的电脑上没有安装这个字体,系统会用一个它认为相似的默认字体来代替。
-
-
26
-
意思:字体的点大小。
-
白话:字的大小是 26 磅。这是一个相当大的字号,通常用于标题、海报等需要醒目的地方。对比一下,Word 里正文常用的是 10.5 或 12 磅。
-
-
-1
-
意思:字体的粗细程度。
-
白话:这是一个特殊值,表示“默认”粗细。通常对应
QFont::Normal
。-1
会让系统根据其他设置自动选择一个合适的粗细,你不需要手动指定它是不是加粗。
-
-
5
-
意思:字体样式,主要是指是否斜体。
-
白话:这里的
5
对应QFont::StyleItalic
,意思是这个字体被设置为斜体。如果是0
就是正常(不斜体)。
-
-
50
-
意思:字体的权重。
-
白话:这个也是控制字体的粗细,但比第三个参数更精细。范围是 0(最细)到 99(最粗)。
50
是正常粗细(Normal)。如果你设为75
,就是加粗(Bold)。这里设置为 50,和上面的“默认”粗细(-1)是匹配的。
-
-
0
-
意思:下划线。
-
白话:
0
表示false
,所以文字没有下划线。如果这里是1
(true),文字下面就会有一条横线。
-
-
0
-
意思:删除线。
-
白话:
0
表示false
,所以文字中间没有横线(删除线)。如果是1
,就会有一条线从文字中间穿过。
-
-
0
-
意思:字符拉伸。
-
白话:
0
表示不拉伸,保持字体原本的宽高比例。如果设置成 150,文字就会在水平方向上被拉宽到 150%;设置成 50,就会被压扁到 50%。
-
-
0
-
意思:字母大小写。
-
白话:
0
表示QFont::MixedCase
,即保持原样,不改变大小写。如果设置成其他值,可以强制把所有字母变成大写或小写。
-
-
0
-
意思:大小写字母高度。
-
白话:这是一个比较专业的排版属性。
0
表示QFont::MixedCase
,使用标准的大写字母高度。如果设置成1
(SmallCaps),会让小写字母也显示成大写字母的样子,但尺寸会小一点。
-
-
"Regular"
-
意思:样式名称。
-
白话:指定字体的特定变体。比如一个字体家族可能有 “Regular”(常规)、“Light”(细体)、“Condensed”(紧缩)等多种样式。这里指定为 “Regular”,就是使用最常规的那一款。如果留空字符串
""
,就使用默认款式。
-
如果说你不是很喜欢上面这个情况,我们也可以逐个打印
我们看看点击Cancel的情况
我们再次呼叫出这个对话框
当然,我们可以点击一下Cancel即可
他则是会打印下面这个
把用户选择的相关字体设置到这个按钮上的字体上
我想修改这个按钮上面的字体样式
其实这个是非常简单的
我们运行一下
点击一下
我们点击ok
很完美吧。
5.5.QInputDialog
这里涉及3个核心方法
1. 双精度浮点型输入对话框 getDouble()
这个方法用于让用户输入一个小数(浮点数)。
double getDouble(QWidget *parent, // 父窗口,通常是当前窗口的this指针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() // 窗口标志,一般用默认值
);
参数
parent(父窗口):
-
指定对话框的父窗口,通常是
this
-
这样对话框会显示在父窗口中央,并且是模态的(阻塞父窗口)
title(标题):
-
显示在对话框标题栏的文字
-
例如:"设置"、"输入"、"选择"等
label(标签):
-
显示在输入框前面的提示文字
-
例如:"请输入姓名:"、"请选择性别:"等
value(默认值):
-
对话框打开时输入框中显示的值
-
用户可以直接使用或修改这个值
min/max(最小/最大值):
-
限制用户输入的范围
-
在 getInt 和 getDouble 中有效
ok 参数:
-
这是一个输出参数,用于判断用户的操作
-
如果用户点击"确定",
*ok
为 true -
如果用户点击"取消"或关闭对话框,
*ok
为 false -
在使用时,通常需要检查这个值来决定是否处理输入
返回值类型:
double
(双精度浮点数)
返回值说明:
-
当用户点击"确定"时:返回用户输入的小数值
-
当用户点击"取消"时:返回默认值(value参数的值)
使用示例:
我们运行一下
弹出对话框
点击ok
如果我们点击Cancel,则会打印下面这个
2. 整型输入数据对话框 getInt()
这个方法用于让用户输入一个整数。
int getInt(QWidget *parent, // 父窗口const QString &title, // 对话框标题const QString &label, // 提示文字int value = 0, // 默认值int min = -2147483647, // 最小值int max = 2147483647, // 最大值int step = 1, // 每次点击增减按钮的变化步长bool *ok = nullptr, // 用户操作结果Qt::WindowFlags flags = Qt::WindowFlags() // 窗口标志
);
这个的参数和上面那个是一样的
返回值说明:
-
当用户点击"确定"时:返回用户输入的整数值
-
当用户点击"取消"时:返回默认值(value参数的值)
使用示例:
我们运行一下
点击一下
我们点击OK
如果点击Cancel
3. 选择条目型输入数据框 getItem()
这个方法显示一个下拉列表,让用户从中选择一个选项。
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 // 输入法提示
);
这个函数的参数和上面两个是差不多的啊
返回值说明:
-
当用户点击"确定"时:
-
如果用户从列表中选择:返回选中的字符串
-
如果可编辑且用户输入了新值:返回用户输入的字符串
-
-
当用户点击"取消"时:返回默认选中的字符串(根据current索引)
使用示例:
点击按钮
点击OK