目录
在一个电脑桌面程序的日常使用中,弹出一个对话框来做提示一个消息、输入一些数据、选择一个文件等各种操作是比较常见的,下面就对Pyqt中的对话框做个简单介绍,看看qt提供的对话框有哪些,如何使用,以及自定义对话框。
1、QDialog
qt现有的各式对话框都是QDialog的子类,QDialog基本不会直接使用,它主要提供对话框的基础功能。对话框有两种运行模式:模态和非模态。
模态:通过exec()/exec_() 或者 setModal(true) or setWindowModality()+show()来运行
非模态:通过show()运行。
exec()/exec_()会阻塞整个应用的执行,即exec()返回之后,代码才会继续执行。该方法返回QDialog::Accepted或QDialog::Rejected,我们可以通过返回值判断用户的选择。
虽然运行dialog最常用的方式是exec()/exec_(),但是show()也有会用到的情况,show()都是立即返回而且没有返回值的,这时候我们要判断用户的选择就需要用到accepted和rejected这两个信号(finished也是可以的)。
accepted信号:在用户点击OK键、调用accept()、使用QDialog.Accepted调用done()的情况下会发出。
rejected信号:在用户点击Cancel键、关闭对话框、调用reject()、使用QDialog.Rejected调用done()的情况下会发出。
只要用自己的槽连接这两个信号,就可以在用户做出选择的时候收到消息。
更多详细基础功能可以参见:QDialog详细说明
2、QColorDialog
QColorDialog提供一个对话框来选择颜色,这个对话框用于得到一个QColor对象。
详细使用见:QColorDialog详细说明
下面是使用QColorDialog的代码示例:
# 方式1:使用便捷函数getColor
sel_color = QColorDialog.getColor(title="选择颜色")
if sel_color.isValid():
print('select color: #{:02x}{:02x}{:02x}'.format(sel_color.red(), sel_color.green(), sel_color.blue()))
# 方式2:自己实例化QColorDialog并处理返回值
self.color_dialog = QColorDialog()
self.color_dialog.setWindowTitle("选择颜色")
if self.color_dialog.exec_() == QDialog.Accepted:
cur_color = self.color_dialog.currentColor()
print('select color: #{:02x}{:02x}{:02x}'.format(cur_color.red(), cur_color.green(), cur_color.blue()))
3、QFontDialog
和QColorDialog的用法差不多,不过 QFontDialog对话框是用来选择字体,最终得到一个QFont对象,详细用法见:QFontDialog详细说明
QFontDialog使用代码示例:
# 方式1:使用便捷函数getFont,该方法返回一个元组(sel_font, is_accept),sel_font是QFont对象
# 一般点OK按钮is_accept=True,其他情况都是False
# is_accept=True时sel_font是选择的字体,否则sel_font是初始化的字体
sel_font, wh = QFontDialog.getFont()
print(sel_font.family(), wh)
# 方式2:自然就是实例化QFontDialog并处理返回值
self.font_dialog = QFontDialog()
self.font_dialog.setWindowTitle('选择字体')
if self.font_dialog.exec_() == QFontDialog.Accepted:
print(self.font_dialog.currentFont().family())
4、QProgressDialog
QProgressDialog提供一个进度条(QProgressBar)来指示一个耗时操作的执行进度,进度条的当前进度需要持续不断的调用 setValue()来设置,这样的话再用exec()来执行就不合适了,一般是把QProgressDialog设置为模态,然后用show()来执行。
QProgressDialog提供一个取消按钮为用户提供中止操作的机会。
详细用法参见:QProgressDialog详细说明
def btn_3_click(self):
# 创建QProgressDialog
self.progress_dialog = QProgressDialog(self)
# 设置最大和最小进度
self.progress_dialog.setMaximum(100)
self.progress_dialog.setMinimum(1)
self.cur_value = 1
# 模态
self.progress_dialog.setModal(Qt.WindowModal)
# QProgressDialog被用户关闭时发出canceled信号
self.progress_dialog.canceled.connect(self.task_cancel)
self.progress_dialog.show()
# 用一个定时器模拟耗时任务进度
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress)
self.timer.start(1000)
def task_cancel(self):
self.timer.stop()
def update_progress(self):
if self.cur_value >= 100:
self.progress_dialog.cancel()
self.timer.stop()
else:
# 不断更新进度
self.progress_dialog.setValue(self.cur_value)
self.cur_value += 5
5、QInputDialog
QInputDialog提供一个对话框用于从用户处获取单个值,其实就是通过一个输入控件来获取。
输入控件有5种:QSpinBox、QDoubleSpinBox、QLineEdit、QTextEdit、QComBoBox分别用来获取整数、小数、单行文本、多行文本、选项值。
注意:QInputDialog只能提供其中之一,不能提供多个,这就是为什么只能获取单个值。
QInputDialog的创建可以使用对应的便捷函数:getInt()、getDouble()、getText()、getMultiLineText()、getItem(),也可以实例化QInputDialog,然后用QInputDialog::InputMode配合QInputDialog::InputDialogOption来获取不同类型的值。
详细用法参见:QInputDialog详细说明
# 方式1:使用便捷函数
print(QInputDialog.getDouble(self, 'Double对话框', '请输入小数'))
print(QInputDialog.getInt(self, 'Int对话框', '请输入整数'))
print(QInputDialog.getText(self, '字符串对话框', '请输入文本'))
print(QInputDialog.getMultiLineText(self, '多行字符串对话框', '请输入多行文本'))
print(QInputDialog.getItem(self, '选项对话框', '请选择', ['语文', '数学', '英语']))
# 方式2:实例化QInputDialog
self.input_dialog = QInputDialog()
# InputMode有TextInput、IntInput、TextInput三种类型
self.input_dialog.setInputMode(QInputDialog.InputMode.TextInput)
# 这个option用于指定多行文本选项框
self.input_dialog.setOption(QInputDialog.UsePlainTextEditForTextInput)
# InputMode是没有ComboBox这个选项的,要使用选项对话框,就调用setComboBoxItems()设置选项列表
# 这个方法会覆盖setInputMode(),使QInputDialog成为选项对话框
#self.input_dialog.setComboBoxItems(['语文', '数学', '英语'])
self.input_dialog.exec_()
各种类型的效果图如下:
6、QFileDialog
QFileDialog提供一个对话框让用户选择文件或目录。
QFileDialog的用法比较多,如果要了解详细的用法还是应该查阅官方文档:QFileDialog详细说明
这里通过其相关快捷函数大致了解一下其用法:
① 选择本地目录
def getExistingDirectory(parent: QWidget | None = ...,
caption: str = ...,
directory: str = ...,
options: Options | Option = ...) -> str
'''
该函数在用户选择一个目录后返回这个目录的完整路径
参数可以指定对话框标题、打开的初始目录、目录选项
'''
② 选择本地/远程目录
def getExistingDirectoryUrl(parent: QWidget | None = ...,
caption: str = ...,
directory: QUrl = ...,
options: Options | Option = ...,
supportedSchemes: Iterable[str] = ...) -> QUrl
'''
这个函数的用法和getExistingDirectory是很相似的,返回的是目录的QUrl
最大的不同是这个函数可以选择一个远程目录,而supportedSchemes参数用于指定
支持的远程协议
'''
③ 选择文件
def getOpenFileName(parent: QWidget | None = ...,
caption: str = ...,
directory: str = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...) -> tuple[str, str]
'''
选择一个文件,返回一个元组,第一个值该文件包含路径的完整文件名,第二个是使用的filter
caption: 标题 directory:初始目录
filter:文件类型过滤器,默认是 All Files (*),多个过滤器用 ;; 分隔
initialFilter: 如果有filter有多个过滤器的话,用于指定初始过滤器
例如filter='Python file (*.py);;Ui file (*.ui)'
那么initialFilter就可以设置成'Python file (*.py)' 或 'Ui file (*.ui)'
'''
def getOpenFileNames(parent: QWidget | None = ...,
caption: str = ...,
directory: str = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...) -> tuple[list[str], str]
'''
选择一个/多个文件,返回一个元组,第一个值是文件名列表,第二个值是使用的filter
caption: 标题 directory:初始目录
filter:文件类型过滤器,默认是 All Files (*),多个过滤器用 ;; 分隔
initialFilter: 如果有filter有多个过滤器的话,用于指定初始过滤器
例如filter='Python file (*.py);;Ui file (*.ui)'
那么initialFilter就可以设置成'Python file (*.py)' 或 'Ui file (*.ui)'
'''
④ 选择本地/远程文件
def getOpenFileUrl(parent: QWidget | None = ...,
caption: str = ...,
directory: QUrl = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...,
supportedSchemes: Iterable[str] = ...) -> tuple[QUrl, str]
def getOpenFileUrls(parent: QWidget | None = ...,
caption: str = ...,
directory: QUrl = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...,
supportedSchemes: Iterable[str] = ...) -> tuple[list[QUrl], str]
'''
不用过多解释了,无论是函数作用还是参数都可以参见上面那几个函数的说明
'''
⑤ 文件另存为
def getSaveFileName(parent: QWidget | None = ...,
caption: str = ...,
directory: str = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...) -> tuple[str, str]
def getSaveFileUrl(parent: QWidget | None = ...,
caption: str = ...,
directory: QUrl = ...,
filter: str = ...,
initialFilter: str = ...,
options: Options | Option = ...,
supportedSchemes: Iterable[str] = ...) -> tuple[QUrl, str]
'''
getOpenFileName是选择文件,而这个是文件另存为
参数就参见上面的几个函数,用法都是一样的
'''
通过这几个便捷函数的参数介绍,大致就能看出来可以给QFileDialog设置的相关参数了,在自己实例化QFileDialog时能设置的方面大致也就这些了。
7、QMessageBox
QMessageBox一般用于弹框给用户提示一个消息,或者给用户展示一个问题并接收用户的答案(一般就是 是/否)。
下面是一个标准的消息框:
可以设置的内容主要就是4大块:1-标题;2-消息图标;3-消息文本;4-按钮。
QMessageBox也提供了一些便捷方法。
详细用法见:QMessageBox详细说明
8、QErrorMessage
QErrorMessage是一个错误消息显示框。它显示一个错误消息并提供一个checkbox让用户选择这个错误消息以后是否再次显示。这个以后指的是这个QErrorMessage的生命周期内。
这个QErrorMessage可以自己实例化并保存好防止被销毁,也可以通过便捷函数 qtHandler() 来获取。QErrorMessage使用方法 showMessage() 来指定消息并显示。
详细说明见:QErrorMessage详细说明
def btn_7_click(self):
self.error_message = QErrorMessage.qtHandler()
self.error_message.showMessage("缺少关键参数")
9、QWizard
QWizard(向导)是一种特殊类型的输入对话框,由一系列页面组成。向导的目的是引导用户逐步完成流程。最常见到的就是安装程序的向导界面了。
既然是向导,那自然需要多个页面,每次下一步都是一个新的页面。
QWizard的每个页面都是一个QWizardPage。
这个一般用不到,这里就不详细说了,具体用法可以看官网文档:QWizard详细说明
下面是官网给的示例效果图: