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_())
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~