QMessageBox 对话视窗
QMessageBox 是 PyQt5 里的对话视窗元件,通常会搭配按钮或选单,打开对话视窗与用户互动,这篇教学会介绍如何在 PyQt5 视窗里加入 QMessageBox 对话视窗,并透过对话视窗进行打开文件或关闭视窗等基本互动应用。
快速导览:
- PyQt6 版本参考:PyQt6 教学 - QMessageBox 对话视窗
- 因为 Google Colab 不支援 PyQt5,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。
加入 QMessageBox 对话视窗
建立 PyQt5 视窗对象后,先透过 QtWidgets.QPushButton(widget) 方法加入按钮,使用 clicked.connect() 绑定点击按钮时的函数,点击按钮时使用 QtWidgets.QMessageBox() 方法建立对话视窗,接着使用 information() 方法,就能打开信息通知的对话视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 300)
def show():
mbox = QtWidgets.QMessageBox(Form) # 加入對話視窗
mbox.information(Form, 'info', 'hello') # 開啟資訊通知的對話視窗,標題 info,內容 hello
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('彈出視窗')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
QMessageBox 的类型
QMessageBox 默认提供下列几种默认类型 ( 四种方法都包含第四个参数 ButtonRole,通常不会设定,直接使用默认值 ):
| 方法 | 参数 | 说明 |
|---|---|---|
| information() | parent, title, text | 信息通知对话视窗。 |
| question() | parent, title, text | 二选一问题对话视窗。 |
| warning() | parent, title, text | 警告视窗。 |
| critical() | parent, title, text | 关键警告视窗 |
下方的程序码执行后,画面中会有四颗按钮,点击后分别会出现不同的对话视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show(n):
mbox = QtWidgets.QMessageBox(Form)
if n==1:
mbox.information(Form, 'information', 'information...')
elif n == 2:
mbox.question(Form, 'question', 'question?')
elif n == 3:
mbox.warning(Form, 'warning', 'warning!!!')
elif n == 4:
mbox.critical(Form, 'critical', 'critical!!!')
btn1 = QtWidgets.QPushButton(Form)
btn1.move(10, 10)
btn1.setText('information')
btn1.clicked.connect(lambda: show(1))
btn2 = QtWidgets.QPushButton(Form)
btn2.move(10, 40)
btn2.setText('question')
btn2.clicked.connect(lambda: show(2))
btn3 = QtWidgets.QPushButton(Form)
btn3.move(10, 70)
btn3.setText('waring')
btn3.clicked.connect(lambda: show(3))
btn4 = QtWidgets.QPushButton(Form)
btn4.move(10, 100)
btn4.setText('critical')
btn4.clicked.connect(lambda: show(4))
Form.show()
sys.exit(app.exec_())
自订 QMessageBox 对话视窗
除了四种默认类型,QMessageBox 也提供“自订对话视窗”的功能,自订视窗的基本写法先透过 setText() 方法设定通知的文字,接着使用 exec() 方法执行,下方的程序码执行后,点击按钮会出现一个没有 icon 的单纯通知视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello') # 通知文字
mbox.exec() # 執行
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
自订对话视窗默认没有 icon 图示,使用 setIcon() 方法可以添加 icon 图示,QMessageBox 提供四种默认 icon 图示,直接输入代号就会出现对应的 icon 图示。
| 图示 | 代号 | 说明 |
|---|---|---|
| QMessageBox.Information | 1 | 信息。 |
| QMessageBox.Warning | 2 | 警告。 |
| QMessageBox.Critical | 3 | 重要警告。 |
| QMessageBox.Question | 4 | 问题。 |
下方的程序码执行后,点击按钮就会出现带有问号 icon 图示的对话视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello?')
mbox.setIcon(4) # 加入問號 icon
# mbox.setIcon(QtWidgets.QMessageBox.Question) # 效果等同這一段
mbox.exec()
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
自订 QMessageBox 按钮
使用 addButton() 方法可以在自订对话视窗中增加按钮,QMessageBox 默认提供下列几种常用的按钮,默认按钮有其固定位置,无法指定位置。
| 按钮 | 呈现文字 | 对应 ButtonRole |
|---|---|---|
| QMessageBox.Ok | Ok | AcceptRole |
| QMessageBox.Open | Open | AcceptRole |
| QMessageBox.Save | Save | AcceptRole |
| QMessageBox.Cancel | Save | RejectRole |
| QMessageBox.Close | Close | RejectRole |
| QMessageBox.Discard | Don't Save | DestructiveRole |
| QMessageBox.Apply | Apply | AcceptRole |
| QMessageBox.Reset | Reset | ResetRole |
| QMessageBox.RestoreDefaults | Restore Defaults | ResetRole |
| QMessageBox.Help | Help | HelpRole |
| QMessageBox.SaveAll | Save All | AcceptRole |
| QMessageBox.Yes | Yes | YesRole |
| QMessageBox.YesToAll | Yes to All | YesRole |
| QMessageBox.No | No | NoRole |
| QMessageBox.NoToAll | No to All | NoRole |
| QMessageBox.Abort | Abort | RejectRole |
| QMessageBox.Retry | Retry | AcceptRole |
| QMessageBox.Ignore | Ignore | AcceptRole |
| QMessageBox.NoButton | 停用 Button |
下方的程序码执行后,点击按钮会出现带有四个按钮的对话视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
mbox.addButton(QtWidgets.QMessageBox.Ok)
mbox.addButton(QtWidgets.QMessageBox.Open)
mbox.addButton(QtWidgets.QMessageBox.Save)
mbox.addButton(QtWidgets.QMessageBox.Cancel)
mbox.exec()
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
如果是默认的按钮,也可以使用 setStandardButtons() 方法添加按钮,添加的写法如下方程序码所示 ( 同时使用 setDefaultButton() 方法设定默认按钮 ):
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
# 添加三顆按鈕
mbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel)
# 設定預設按鈕
mbox.setDefaultButton(QtWidgets.QMessageBox.Yes)
mbox.exec()
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
如果不想用默认按钮文字,也可以直接输入按钮文字,但如果要自订文字,需要包含第二个参数 ButtonRole,常用的 ButtonRole 如下:
| ButtonRole | 代码 | 说明 |
|---|---|---|
| QMessageBox.ButtonRole.InvalidRole | -1 | 按钮无效。 |
| QMessageBox.ButtonRole.AcceptRole | 0 | 接受。 |
| QMessageBox.ButtonRole.RejectRole | 1 | 拒绝。 |
| QMessageBox.ButtonRole.DestructiveRole | 2 | 破坏性更改。 |
| QMessageBox.ButtonRole.ActionRole | 3 | 发生行为。 |
| QMessageBox.ButtonRole.HelpRole | 4 | 请求帮助。 |
| QMessageBox.ButtonRole.YesRole | 5 | 等同“是”。 |
| QMessageBox.ButtonRole.NoRole | 6 | 等同“否”。 |
| QMessageBox.ButtonRole.ApplyRole | 7 | 同意。 |
| QMessageBox.ButtonRole.ResetRole | 8 | 设为默认值。 |
下方的程序码执行后,点击按钮会出现一个带有三颗自订文字按钮的对话视窗。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
mbox.addButton('Apple', 3)
mbox.addButton('Banana', 3)
mbox.addButton('Orange', 3)
mbox.exec()
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
透过 setDefaultButton() 方法,可以指定那一颗按钮预先选取 ( 打开对话视窗时预先变色 ),下方的程序码执行后,会预先选取 Banana 的按钮。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
a = mbox.addButton('Apple',3) # 前方多了變數 a
b = mbox.addButton('Banana',3) # 前方多了變數 b
c = mbox.addButton('Orange',3) # 前方多了變數 c
mbox.setDefaultButton(b) # 預先選取 b
mbox.exec()
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
QMessageBox 点击事件
如果要取得 QMessageBox 点击事件,可以将最后 exec() 执行方法宣告为变数,该变数为一组数字,如果是默认按钮,可以直接透过 if 判断式进行判断,就可以知道点击了哪个按钮。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
mbox.setStandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel)
mbox.setDefaultButton(QtWidgets.QMessageBox.Yes)
ret = mbox.exec() # 取得點擊的按鈕數字
if ret == QtWidgets.QMessageBox.Yes:
print(1)
elif ret == QtWidgets.QMessageBox.No:
print(2)
elif ret == QtWidgets.QMessageBox.Cancel:
print(3)
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
如果是自订按钮,则 ret 可以采用“顺序”的方式,最先添加的按钮顺序为 0,接着依序增加,只要知道顺序,就能知道点击了哪颗按钮。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
a = mbox.addButton('Apple',3) # 前方多了變數 a,順序 0
b = mbox.addButton('Banana',3) # 前方多了變數 b,順序 1
c = mbox.addButton('Orange',3) # 前方多了變數 c,順序 2
mbox.setDefaultButton(b) # 預先選取 b
ret = mbox.exec()
print(ret)
if ret == 0:
print('Apple')
if ret == 1:
print('Banana')
if ret == 2:
print('Orange')
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
如果不想要使用“顺序”作为判断依据,也可以使用 mbox.clickedButton().text() 方法取得点击按钮的文字,再透过 if 判断式就能知道点击了哪颗按钮。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
def show():
mbox = QtWidgets.QMessageBox(Form)
mbox.setText('hello')
a = mbox.addButton('Apple',3) # 前方多了變數 a
b = mbox.addButton('Banana',3) # 前方多了變數 b
c = mbox.addButton('Orange',3) # 前方多了變數 c
mbox.setDefaultButton(b) # 預先選取 b
mbox.exec()
text = mbox.clickedButton().text() # 取得點擊的按鈕文字
if text == 'Apple':
print('Apple')
if text == 'Banana':
print('Banana')
if text == 'Orange':
print('Orange')
btn = QtWidgets.QPushButton(Form)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(show)
Form.show()
sys.exit(app.exec_())
改用 class 的写法
上方的程序码,亦可改用 class 的写法表示。
from PyQt5 import QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
btn = QtWidgets.QPushButton(self)
btn.move(10, 10)
btn.setText('open')
btn.clicked.connect(self.showBox)
def showBox(self):
mbox = QtWidgets.QMessageBox(self)
mbox.setText('hello')
a = mbox.addButton('Apple',3)
b = mbox.addButton('Banana',3)
c = mbox.addButton('Orange',3)
mbox.setDefaultButton(b)
mbox.exec()
text = mbox.clickedButton().text()
if text == 'Apple':
print('Apple')
if text == 'Banana':
print('Banana')
if text == 'Orange':
print('Orange')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec_())
微信扫码关注
抖音扫码关注