对话框是指有主窗口弹出的、起到提示、警告、接受输入等功能的子窗口。
PyQt5中提供了自定义对话框(QDialog)、消息对话框(QMessageBox)、输入对话框(QInputDialog)、字体对话框(QFontDialog)、颜色对话框(QColorDialog)和文件对话框(QFileDialog)
对话框(QDialog)
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class QDialogDemo(QMainWindow):
def __init__(self):
super(QDialogDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QDialog案例")
self.resize(300, 200)
# 设置文本内容 + 直接固定到主窗口
self.button = QPushButton("弹出对话框", self)
self.button.move(50, 50)
self.button.clicked.connect(self.showDialog)
def showDialog(self):
# 创建对话框控件,并在对话框中创建新的控件
dialog = QDialog()
button = QPushButton("确定", dialog)
# dialog的close方法作用是将对话框关闭
button.clicked.connect(dialog.close)
button.move(50, 50)
dialog.setWindowTitle("对话框")
# 让对话框以模式的状态显示,即触发对话框后,主窗口的控件时无法使用的
dialog.setWindowModality(Qt.ApplicationModal)
# 最后不要忘了调用exec来执行创建的对话框
dialog.exec()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QDialogDemo()
main.show()
sys.exit(app.exec_())
运行结果:

点击“弹出对话框“的按钮,就会弹出小的对话框,并且此时无法点击主窗口的任控件
消息对话框(QMessageBox)
除了QDialog这样的自定义对话框,PyQt5还提供了一些常用的功能对话框
- 关于对话框
- 错误对话框
- 警告对话框
- 提问对话框
- 消息对话框
差异:
- 显示的对话框图标可能不同(有的对话框不现实图标)
- 显示的按钮是不一样的
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class QMessageBoxDemo(QWidget):
def __init__(self):
super(QMessageBoxDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QMessageBox案例")
self.resize(300, 400)
# 创建垂直布局
layout = QVBoxLayout()
# 设置关于对话框
self.button1 = QPushButton("显示关于对话框")
self.button1.clicked.connect(self.showDialog)
# 设置消息对话框
self.button2 = QPushButton("显示消息对话框")
self.button2.clicked.connect(self.showDialog)
# 设置警告对话框
self.button3 = QPushButton("显示警告对话框")
self.button3.clicked.connect(self.showDialog)
# 设置错误对话框
self.button4 = QPushButton("显示错误对话框")
self.button4.clicked.connect(self.showDialog)
# 设置提问对话框,一般是询问用户是否保存
self.button5 = QPushButton("显示提问对话框")
self.button5.clicked.connect(self.showDialog)
layout.addWidget(self.button1)
layout.addWidget(self.button2)
layout.addWidget(self.button3)
layout.addWidget(self.button4)
layout.addWidget(self.button5)
self.setLayout(layout)
def showDialog(self):
text = self.sender().text()
if text == "显示关于对话框":
# 参数:主窗口, 标题, 内容
QMessageBox.about(self, "关于", "这是一个关于对话框")
elif text == "显示消息对话框":
# 参数:主窗口, 标题, 内容, 选项(QMessageBox常量用|分隔), 默认的选项(QMessageBox常量)
reply = QMessageBox.information(self, "消息", "这是一个消息对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
print(reply == QMessageBox.Yes)
elif text == "显示警告对话框":
QMessageBox.warning(self, "警告", "这是一个警告对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
elif text == "显示错误对话框":
QMessageBox.critical(self, "错误", "这是一个错误对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
elif text == "显示提问对话框":
QMessageBox.question(self, "提问", "这是一个提问对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QMessageBoxDemo()
main.show()
sys.exit(app.exec_())
运行结果:

点击按钮会分别展示出以下五种类型的提示框:

QMessageBox.about()
:关于对话框对象。QMessageBox.information()
:消息对话框对象。QMessageBox.warning()
:警告对话框对象。QMessageBox.critical()
:错误对话框对象。QMessageBox.question()
:提问对话框对象。
需要说明的是,每个类的构造函数都接受这样几个参数,载入的主窗体、标题、内容。比如我们程序中写的:
QMessageBox.about(self, "关于", "这是一个关于对话框")
意思就是在self
(指向主窗体的指针)下,创建一个标题为“关于”,内容为“这是一个关于对话框”的关于对话框。
除此之外,我们还可以设置选项按钮:
QMessageBox.warning(self, "警告", "这是一个警告对话框", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
QMessageBox.Yes | QMessageBox.No
表示增加Yes和No两个按钮(可以使用热键),其中QMessageBox.Yes
和QMessageBox.No
都是常量(QMessageBox.Yes=16384, QMessageBox.No=65536),用|
连接,类似C++中的ios::in|ios::out
,表示这两个按钮都添加。(由于
最后一个参数代表弹出对话框后,默认选中的按钮(选择Yes为默认代表刚刚弹出对话框后按下回车键后触发Yes按钮)
输入对话框
允许用户输入数据的对话框为输入对话框,共有三种:
QInputDialog.getItem
:选择选项的下拉列表。QInputDialog.getText
:获取输入的文本内容。QInputDialog.getInt
:获取输入数字的计时器。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class QInputDialogDemo(QWidget):
def __init__(self):
super(QInputDialogDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("输入对话框")
layout = QFormLayout()
self.button1 = QPushButton("获取列表中的选项")
self.button1.clicked.connect(self.getItem)
self.lineEdit1 = QLineEdit()
layout.addRow(self.button1, self.lineEdit1)
self.button2 = QPushButton("获取字符串")
self.button2.clicked.connect(self.getText)
self.lineEdit2 = QLineEdit()
layout.addRow(self.button2, self.lineEdit2)
self.button3 = QPushButton("获取整数")
self.button3.clicked.connect(self.getInt)
self.lineEdit3 = QLineEdit()
layout.addRow(self.button3, self.lineEdit3)
self.setLayout(layout)
def getItem(self):
items = ('C', 'C++', 'Ruby', 'Python', 'Java')
# 返回两个值,第一个item代表用户选择的值,ok代表用户是否按下了取消
item, ok = QInputDialog.getItem(self, "请选择编程语言", "语言列表", items)
if ok and item:
self.lineEdit1.setText(item)
def getText(self):
text, ok = QInputDialog.getText(self, "文本输入框", "输入姓名")
if ok and text:
self.lineEdit2.setText(text)
def getInt(self):
num, ok = QInputDialog.getInt(self, "整数输入框", "输入数字")
if ok and num:
self.lineEdit3.setText(str(num))
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QInputDialogDemo()
main.show()
sys.exit(app.exec_())
运行效果:


可以看到QInputDialog.getItem
就是一个下拉列表,QInputDialog.getText
就是一个文本输入框,QInputDialog.getInt
就是一个计数器。
字体对话框(QFontDialog)
弹出一个可以选择字体属性的对话框。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class QFontDialogDemo(QWidget):
def __init__(self):
super(QFontDialogDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QFontDialog实例")
self.resize(300, 200)
layout = QVBoxLayout()
self.fontButton = QPushButton("选择字体")
self.fontButton.clicked.connect(self.getFont)
layout.addWidget(self.fontButton)
self.fontLabel = QLabel("Hello, 测试字体例子")
layout.addWidget(self.fontLabel)
self.setLayout(layout)
def getFont(self):
font, ok = QFontDialog.getFont()
if ok:
self.fontLabel.setFont(font)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QFontDialogDemo()
main.show()
sys.exit(app.exec_())
运行效果:


点击“选择字体”便会弹出这样一个对话框
选择字体属性后,静态函数QFontDialog.getFont()
会根据用户选择的字体属性生成一个字体属性对象font
,这个对像可作为各类控件getFont()
方法额参数,进而改变它们文本的字体属性。QFontDialog.getFont()
返回的第二个值储存在ok
中,若用户点击了OK,那么ok
就为True
;若用户点击了Cancel,那么ok
就为False
。
颜色对话框(QColorDialog)
弹出一个可以选择字体颜色和背景色的对话框。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class QColorDialogDemo(QWidget):
def __init__(self):
super(QColorDialogDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("QFontDialog实例")
self.resize(300, 200)
layout = QVBoxLayout()
self.colorButton1 = QPushButton("设置字体颜色")
self.colorButton1.clicked.connect(self.getColor)
layout.addWidget(self.colorButton1)
self.colorButton2 = QPushButton("设置背景颜色")
self.colorButton2.clicked.connect(self.getBGColor)
layout.addWidget(self.colorButton2)
self.colorLabel = QLabel("Hello, 测试字体例子")
layout.addWidget(self.colorLabel)
self.setLayout(layout)
def getColor(self):
color= QColorDialog.getColor()
# 设置调色板颜色
p = QPalette()
p.setColor(QPalette.WindowText, color)
self.colorLabel.setPalette(p)
def getBGColor(self):
color = QColorDialog.getColor()
p = QPalette()
p.setColor(QPalette.Window, color)
self.colorLabel.setAutoFillBackground(True)
self.colorLabel.setPalette(p)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QColorDialogDemo()
main.show()
sys.exit(app.exec_())
运行结果:


点击“设置颜色”或者“设置背景颜色”按钮,会弹出这样一个对话框
需要注意的是,PyQt5对字体颜色的设置是通过调色板来完成的,需要先通过QPalette()
创建一个调色板,设置这个调色板对象的属性。然后传入窗体对象的setPalette()
方法中。
需要注意的是,不同于上面的QFontDialog
和下面的QFileDialog
,QColorDialog
的getColor()
方法只返回一个值。
文件对话框(QFileDialog)
可以打开文件。
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class QFileDialogDemo(QWidget):
def __init__(self):
super(QFileDialogDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle("文件对话框演示")
layout = QVBoxLayout()
self.button1 = QPushButton("加载图片")
self.button1.clicked.connect(self.loadImage)
layout.addWidget(self.button1)
self.imageLabel = QLabel()
layout.addWidget(self.imageLabel)
self.button2 = QPushButton("加载文本文件")
self.button2.clicked.connect(self.loadText)
layout.addWidget(self.button2)
self.contents = QTextEdit()
layout.addWidget(self.contents)
self.setLayout(layout)
def loadImage(self):
# 参数:主窗口, 对话框标题, 默认的初始路径, 允许加载的文件类型
fname, _ = QFileDialog.getOpenFileName(self, "打开文件", '.', "图像文件(*.jpg *.png)")
# QLabel设置图片的方法为setPixmap,参数为使用图片路径为初始化参数的QPixmap对象
self.imageLabel.setPixmap(QPixmap(fname))
def loadText(self):
dialog = QFileDialog()
# 允许任何文件格式
dialog.setFileMode(QFileDialog.AnyFile)
# 文件过滤,只显示文本文件
dialog.setFilter(QDir.Files)
if dialog.exec():
filenames = dialog.selectedFiles()
# 返回的filenames是一个列表,索引一下
f = open(filenames[0], "r", encoding="utf-8")
with f:
data = f.read()
self.contents.setText(data)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = QFileDialogDemo()
main.show()
sys.exit(app.exec_())
运行结果:


已经选择了要打开的文件
上述使用了两种方法来打开文件,一种是直接使用静态函数方法:QFileDialog.getOpenFileName()
:
QFileDialog.getOpenFileName(self, "打开文件", '.', "图像文件(*.jpg *.png)")
同QFontDialog
的getFont()
方法一样,getOpenFileName()
返回两个值,一个是文代表件路径的字符串,一个是代表用户是否点击取消的布尔值。上述这句话的意思就是在主窗口上(self
)弹出一个标题为“打开文件”的文件对话框("打开文件"
),开始默认的选择窗口为当前窗口('.'
),允许选择的文件为jpg或png格式的图像文件("图像文件(*.jpg *.png)"
)
第二种为通过创建QFileDialog
,通过其方法过滤实现文件等功能,最后通过selectFiles()
方法获取一个装有文件路径的列表,后面可以直接通过Python打开文件的方法打开。