Python PyQt5:如何使用PyQt5显示错误消息

25

在正常的Python(3.x)中,我们总是使用tkinter模块中的showerror()来显示错误消息,但是在PyQt5中应该怎么做才能显示完全相同类型的消息呢?

7个回答

43

别忘了调用.exec_()来显示错误:

from PyQt5.QtWidgets import QMessageBox

msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setText("Error")
msg.setInformativeText('More information')
msg.setWindowTitle("Error")
msg.exec_()

感谢提供.exec_()提示! - dmitry_romanov
快速简便的解决方案,谢谢。 - ArduinoBen

35

Qt 包含一个 特定于错误消息的对话框类 QErrorMessage,您应该使用它来确保您的对话框符合系统标准。只需创建一个对话框对象,然后调用 .showMessage() 来显示对话框。例如:

error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Oh no!')

这里是一个最小可行示例脚本:

import PyQt5
from PyQt5 import QtWidgets

app = QtWidgets.QApplication([])

error_dialog = QtWidgets.QErrorMessage()
error_dialog.showMessage('Oh no!')

app.exec_()

8
假设您正在一个QWidget中,您想显示一个错误消息,您可以简单地使用QMessageBox.critical(self, "标题", "消息"),如果您不在一个QWidget类中,请替换self为另一个(例如主窗口)。

编辑:即使您不在QWidget中(或者不想继承它),您也可以将None作为父对象,并使用QMessageBox.critical(None, "标题", "消息")


编辑,以下是如何使用的示例:

# -*-coding:utf-8 -*

from PyQt5.QtWidgets import QApplication, QMessageBox
import sys

# In this example, success is False by default, and
#  - If you press Cancel, it will ends with False,
#  - If you press Retry until i = 3, it will end with True


expectedVal = 3


def MyFunction(val: int) -> bool:
    return val == expectedVal


app = QApplication(sys.argv)
i = 1
success = MyFunction(i)
while not success:
    # Popup with several buttons, manage below depending on choice
    choice = QMessageBox.critical(None,
                                  "Error",
                                  "i ({}) is not expected val ({})".format(i, expectedVal),
                                  QMessageBox.Retry | QMessageBox.Cancel)
    if choice == QMessageBox.Retry:
        i += 1
        print("Retry with i = {}".format(i))
        success = MyFunction(i)
    else:
        print("Cancel")
        break

if success:
    # Standard popup with only OK button
    QMessageBox.information(None, "Result", "Success is {}".format(success))
else:
    # Standard popup with only OK button
    QMessageBox.critical(None, "Result", "Success is {}".format(success))


谢谢您!您能告诉我当用户点击弹出的按钮时该怎么进行吗? - Ben
1
不客气,您说的弹出按钮是什么意思?您是指根据用户选择哪个按钮来进行下一步操作吗? - gluttony
是的,当我使用您上面的代码时,会出现一个带有单个按钮的消息框。但是当我点击它时,Python会遇到未处理的异常,我猜这是因为没有定义在单击此按钮时会发生什么? - Ben
1
哦,奇怪,我从来没有遇到过这个问题。我会在我的答案中编辑一个小例子,展示如何管理带有不同按钮的弹出窗口(以及只有一个按钮的弹出窗口)。如果可以的话,你可以尝试一下这个例子是否适用于你。另外,从我所看到的情况来看,使用QMessageBox.critical时,可能会导致异常的原因是没有创建QApplication - gluttony

6

以上所有选项在使用Komodo Edit 11.0时都无法正常工作,只会返回“1”,或者如果未实现则返回“-1073741819”。

对我有用的是:Vanloc的解决方案。

def my_exception_hook(exctype, value, traceback):
    # Print the error and traceback
    print(exctype, value, traceback)
    # Call the normal Exception hook after
    sys._excepthook(exctype, value, traceback)
    sys.exit(1)

# Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook

# Set the exception hook to our wrapping function
sys.excepthook = my_exception_hook

适用于PyQt6和PyCharm,效果很好。 - Kevin Ramirez Zavalza

6
为了显示一个消息框,您可以调用此函数:
from PyQt5.QtWidgets import QMessageBox, QWidget

MainClass(QWidget):
    def __init__(self):
        super().__init__()

    def clickMethod(self):
        QMessageBox.about(self, "Title", "Message")

4
以下方法应该有效:
msg = QMessageBox()
msg.setIcon(QMessageBox.Critical)
msg.setText("Error")
msg.setInformativeText(e)
msg.setWindowTitle("Error")

虽然GUI不同,但是这种消息类型与原来的相似度较高。 e 是Python3中表示错误(Error)的表达式。

希望对你有所帮助, Narusan


你应该写一个数字作为参数,而不是msg.setIcon(QMessageBox.critical)。请参见:http://doc.qt.io/qt-5/qmessagebox.html#Icon-enum - Ramón Wilhelm
@AlanHorman。不,这只是一个打字错误 - 应该是QMessageBox.Critical(即大写的“C”)。 - ekhumoro
抱歉打错了字,我应该仔细检查拼写。 - Narusan

0
import sys
from PyQt5.QtWidgets import QMessageBox
import PyQt5
from PyQt5 import QtWidgets
"""
Stadard button
QMessageBox.Ok
QMessageBox.Open
QMessageBox.Save
QMessageBox.Cancel
QMessageBox.Close
QMessageBox.Yes
QMessageBox.No
QMessageBox.Abort
QMessageBox.Retry
QMessageBox.Ignore
"""

class MessageBox(QMessageBox):
    def __init__(self, parent=None):
        super().__init__(parent)
        
    #showinfo    
    def showinfo(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        
        self.setIcon(QMessageBox.Information)
        self.standard_button=QMessageBox.Ok
        self.setStandardButtons(self.standard_button)
        return self.execute()


    #showwarning
    def showwarning(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Warning)
        self.standard_button=QMessageBox.Ok
        self.setStandardButtons(self.standard_button)
        return self.execute()


    #showerror
    def showerror(self,title,text):
        
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Critical)
        self.standard_button=QMessageBox.Ok
        self.setStandardButtons(self.standard_button)
        return self.execute()
       


    #askyesno
    def askyesno(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Question)
        self.standard_button=QMessageBox.Yes | QMessageBox.No
        self.setStandardButtons(self.standard_button)
        return self.execute()


    #askyesnocancel
    def askyesnocancel(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Question)
        self.standard_button=QMessageBox.Yes | QMessageBox.No| QMessageBox.Cancel
        self.setStandardButtons(self.standard_button)
        return self.execute()

    #asksave
    def asksave(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Question)
        self.standard_button=QMessageBox.Save | QMessageBox.No| QMessageBox.Cancel
        self.setStandardButtons(self.standard_button)
        return self.execute()

    #asksave
    def askopen(self,title,text):
        self.setWindowTitle(title)
        self.setText(text)
        self.setIcon(QMessageBox.Question)
        self.standard_button=QMessageBox.Open | QMessageBox.No
        self.setStandardButtons(self.standard_button)
        return self.execute()

    #execute
    def execute(self):
        self.exec_()
        msg_returned=str(self.clickedButton().text()).replace('&','')
        return msg_returned

    
#Test

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication, QListWidget, QVBoxLayout, QLineEdit,QPushButton



class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Msgbox")
        self.layout=QVBoxLayout()
        self.button=QPushButton("show message box")
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
        self.button.clicked.connect(self.handle_text_changed)

        #messagebox 
        self.msgbox = MessageBox()

    def handle_text_changed(self):
            #res = self.msgbox.showinfo("Title","This is a text")
            #res = self.msgbox.showerror("Title","This is a text")  #askyesnocancel
            #res = self.msgbox.askyesnocancel("Title","This is a text")
            #res = self.msgbox.askyesno("Title","This is a text")
            #res = self.msgbox.showwarning("Title","This is a text")  
            #res = self.msgbox.showerror("Title","This is a text")  
            #res = self.msgbox.asksave("Title","This is a text")  
            #res = self.msgbox.askopen("Title","This is a text")  
            res = self.msgbox.showinfo("Title","This is a text")  
            print(res)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainwindow = Widget()
    mainwindow.show()
    sys.exit(app.exec_())
    
    

`

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接