I want to add a custom button to QMessagebox that opens up a matplotlib window, along with an Ok button for user to click when they want to close it
I currently have it somewhat working, but I want the two buttons to do separate things and not open the window.
I know I can just create a dialog window with the desired results, but I wanted to know how to with a 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()
Desired result:
Ok button - closes QMessageBox
View Graph button - opens matplotlib window and keeps QMessageBox open until user clicks Ok
A QMessageBox, as all QDialogs, blocks everything until exec_()
is returned, but it also automatically connects all buttons to either accepted/rejected signals, returning the exec_()
in any case.
A possible solution for your code is:
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_())
That said, be careful in using QDialog.exec_()
outside (as in "before") the sys.exit(app.exec_())
call, as it might result in unexpected behavior if you don't know what you are doing.
Is there a way to push the QMessageBox back? When I open the graph window, the QMessageBox is always on top and wont let me click on graph window until I close it
That's strange, in my tests (Linux and Wine), using a simple QWidget, it was possible to interact with the other widget too. It's possible that on Windows or MacOS the window stays modal, but setting the modality as shown in the code should prevent that. Did you leave the messagebox without any parent, and are you sure you are using
show()
instead ofexec_()
?setting the modality fixed it, thanks.