QMessageBox 添加自定义按钮并保持打开状态
QMessageBox add custom button and keep open
我想向 QMessagebox 添加一个自定义按钮以打开 matplotlib window,以及一个 Ok 按钮供用户在想要关闭它时单击
我目前可以正常使用,但我希望这两个按钮分别执行操作而不是打开 window。
我知道我可以创建一个具有所需结果的对话框 window,但我想知道如何使用 QMessageBox。
import sys
from PyQt5 import QtCore, QtWidgets
def main():
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QtWidgets.QMessageBox.Ok)
msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)
bttn = msgbox.exec_()
if bttn:
print("Ok")
else:
print("View Graphs")
sys.exit(app.exec_())
if __name__ == "__main__":
main()
想要的结果:
确定按钮 - 关闭 QMessageBox
View Graph 按钮 - 打开 matplotlib window 并保持 QMessageBox 打开直到用户点击 Ok
好的,首先你没有在 QtCore 中使用任何东西,所以不需要导入它。这应该可以帮助您了解您需要做什么。我稍微调整了一下,我不得不添加 2 sys.exits,或者当您按下 View Graphs 时,由于您当前的设置方式,程序刚刚挂起。如果您不选择调整此代码流,则将 sys.exit 从 if/else 中拉出并将其放在 if/else 之后 - 没有不必要的冗余代码
from sys import exit as sysExit
from PyQt5.QtWidgets import QApplication, QMessageBox
def Main():
msgbox = QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QMessageBox.Ok)
msgbox.addButton('View Graphs', QMessageBox.YesRole)
bttn = msgbox.exec_()
if bttn == QMessageBox.Ok:
print("Ok")
sysExit()
else:
print("View Graphs")
sysExit()
if __name__ == "__main__":
MainThred = QApplication([])
MainApp = Main()
sysExit(MainThred.exec_())
也就是你的 non-redundant if/else 看起来如下
if bttn == QMessageBox.Ok:
print("Ok")
else:
print("View Graphs")
sysExit()
IMO 有点老套,但在添加 View Graphs
按钮后,您可以断开其 clicked
信号并将其重新连接到您选择的插槽,例如
import sys
from PyQt5 import QtCore, QtWidgets
def show_graph():
print('Show Graph')
def main():
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QtWidgets.QMessageBox.Ok)
yes_button = msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)
yes_button.clicked.disconnect()
yes_button.clicked.connect(show_graph)
bttn = msgbox.exec_()
if bttn:
print("Ok")
sys.exit(app.exec_())
if __name__ == "__main__":
main()
QMessageBox 和所有 QDialogs 一样,在返回 exec_()
之前阻塞所有内容,但它也会自动将所有按钮连接到任一 accepted/rejected 信号,在任何情况下都返回 exec_()
。
您的代码的可能解决方案是:
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
# the following is if you need to interact with the other window
msgbox.setWindowModality(QtCore.Qt.NonModal)
msgbox.addButton(msgbox.Ok)
viewGraphButton = msgbox.addButton('View Graphs', msgbox.ActionRole)
# disconnect the clicked signal from the slots QMessageBox automatically sets
viewGraphButton.clicked.disconnect()
# this is just an example, replace with your matplotlib widget/window
graphWidget = QtWidgets.QWidget()
viewGraphButton.clicked.connect(graphWidget.show)
msgbox.button(msgbox.Ok).clicked.connect(graphWidget.close)
# do not use msgbox.exec_() or it will reset the window modality
msgbox.show()
sys.exit(app.exec_())
就是说,在 sys.exit(app.exec_())
调用之外(如在 "before" 中)使用 QDialog.exec_()
时要小心,因为如果您不知道自己在做什么,可能会导致意外行为正在做。
我想向 QMessagebox 添加一个自定义按钮以打开 matplotlib window,以及一个 Ok 按钮供用户在想要关闭它时单击
我目前可以正常使用,但我希望这两个按钮分别执行操作而不是打开 window。
我知道我可以创建一个具有所需结果的对话框 window,但我想知道如何使用 QMessageBox。
import sys
from PyQt5 import QtCore, QtWidgets
def main():
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QtWidgets.QMessageBox.Ok)
msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)
bttn = msgbox.exec_()
if bttn:
print("Ok")
else:
print("View Graphs")
sys.exit(app.exec_())
if __name__ == "__main__":
main()
想要的结果:
确定按钮 - 关闭 QMessageBox
View Graph 按钮 - 打开 matplotlib window 并保持 QMessageBox 打开直到用户点击 Ok
好的,首先你没有在 QtCore 中使用任何东西,所以不需要导入它。这应该可以帮助您了解您需要做什么。我稍微调整了一下,我不得不添加 2 sys.exits,或者当您按下 View Graphs 时,由于您当前的设置方式,程序刚刚挂起。如果您不选择调整此代码流,则将 sys.exit 从 if/else 中拉出并将其放在 if/else 之后 - 没有不必要的冗余代码
from sys import exit as sysExit
from PyQt5.QtWidgets import QApplication, QMessageBox
def Main():
msgbox = QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QMessageBox.Ok)
msgbox.addButton('View Graphs', QMessageBox.YesRole)
bttn = msgbox.exec_()
if bttn == QMessageBox.Ok:
print("Ok")
sysExit()
else:
print("View Graphs")
sysExit()
if __name__ == "__main__":
MainThred = QApplication([])
MainApp = Main()
sysExit(MainThred.exec_())
也就是你的 non-redundant if/else 看起来如下
if bttn == QMessageBox.Ok:
print("Ok")
else:
print("View Graphs")
sysExit()
IMO 有点老套,但在添加 View Graphs
按钮后,您可以断开其 clicked
信号并将其重新连接到您选择的插槽,例如
import sys
from PyQt5 import QtCore, QtWidgets
def show_graph():
print('Show Graph')
def main():
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Information")
msgbox.setText('Test')
msgbox.addButton(QtWidgets.QMessageBox.Ok)
yes_button = msgbox.addButton('View Graphs', QtWidgets.QMessageBox.YesRole)
yes_button.clicked.disconnect()
yes_button.clicked.connect(show_graph)
bttn = msgbox.exec_()
if bttn:
print("Ok")
sys.exit(app.exec_())
if __name__ == "__main__":
main()
QMessageBox 和所有 QDialogs 一样,在返回 exec_()
之前阻塞所有内容,但它也会自动将所有按钮连接到任一 accepted/rejected 信号,在任何情况下都返回 exec_()
。
您的代码的可能解决方案是:
app = QtWidgets.QApplication(sys.argv)
msgbox = QtWidgets.QMessageBox()
# the following is if you need to interact with the other window
msgbox.setWindowModality(QtCore.Qt.NonModal)
msgbox.addButton(msgbox.Ok)
viewGraphButton = msgbox.addButton('View Graphs', msgbox.ActionRole)
# disconnect the clicked signal from the slots QMessageBox automatically sets
viewGraphButton.clicked.disconnect()
# this is just an example, replace with your matplotlib widget/window
graphWidget = QtWidgets.QWidget()
viewGraphButton.clicked.connect(graphWidget.show)
msgbox.button(msgbox.Ok).clicked.connect(graphWidget.close)
# do not use msgbox.exec_() or it will reset the window modality
msgbox.show()
sys.exit(app.exec_())
就是说,在 sys.exit(app.exec_())
调用之外(如在 "before" 中)使用 QDialog.exec_()
时要小心,因为如果您不知道自己在做什么,可能会导致意外行为正在做。