添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

QMessageBox 對話視窗

QMessageBox 是 PyQt5 裡的對話視窗元件,通常會搭配按鈕或選單,開啟對話視窗與使用者互動,這篇教學會介紹如何在 PyQt5 視窗裡加入 QMessageBox 對話視窗,並透過對話視窗進行開啟檔案或關閉視窗等基本互動應用。

快速導覽:

  • 加入 QMessageBox 對話視窗
  • QMessageBox 的類型
  • 自訂 QMessageBox 對話視窗
  • 自訂 QMessageBox 按鈕
  • QMessageBox 點擊事件
  • 改用 class 的寫法
  • 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_())
        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 QMessageBox.Warning QMessageBox.Critical 重要警告。 QMessageBox.Question

    下方的程式碼執行後,點擊按鈕就會出現帶有問號 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_())
        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 按鈕無效。 QMessageBox.ButtonRole.AcceptRole QMessageBox.ButtonRole.RejectRole QMessageBox.ButtonRole.DestructiveRole 破壞性更改。 QMessageBox.ButtonRole.ActionRole 發生行為。 QMessageBox.ButtonRole.HelpRole 請求幫助。 QMessageBox.ButtonRole.YesRole 等同「是」。 QMessageBox.ButtonRole.NoRole 等同「否」。 QMessageBox.ButtonRole.ApplyRole QMessageBox.ButtonRole.ResetRole 設為預設值。

    下方的程式碼執行後,點擊按鈕會出現一個帶有三顆自訂文字按鈕的對話視窗。

    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_())
              

    如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

    Python 教學

    Python 學習導讀 關於 Python 使用 Google Colab 使用 Anaconda 使用 Python 虛擬環境 Python 範例集錦 變數 variable 變數 ( 全域、區域 ) 數字 number 文字與字串 string 文字與字串 ( 常用方法 ) 文字與字串 ( 格式化 ) 串列 list 串列 ( 常用方法 ) 元組/數組 tuple 字典 dictionary 集合 set 縮排和註解 運算子 operator 邏輯判斷 ( if、elif、else ) 邏輯判斷 ( and 和 or ) 重複迴圈 ( for、while ) 例外處理 ( try、except ) 生成式 comprehension 物件類別 class 物件繼承 inheritance 匯入模組 import 函式 function 匿名函式 lambda 遞迴 recursion 產生器 generator 裝飾器 decorator 閉包 closure

    內建函式&方法

    輸入與輸出 字串操作與轉換 迭代物件轉換 迭代物件操作 檔案讀寫 ( open ) eval() 與 exec()

    標準函式庫&模組

    隨機數 random 數學 math 數學統計函式 statistics 時間與日期 datetime 時間處理 time 日曆 calendar 使用正規表達式 re 檔案操作 os 查找匹配檔案 glob 壓縮檔案 zipfile 高階檔案操作 shutil 高效迭代器 itertools 容器資料型態 collections CSV 檔案操作 JSON 檔案操作 threading 多執行緒處理 concurrent.futures