Solved QMessageBox clicked standard button with open (not exec_)
-
Hi!
Let's say I have the following
QMessageBox
:class ReallyWantToQuit(QMessageBox): def __init__(self): super().__init__() self.setModal(True) self.setText('Do you really want to quit?') self.setInformativeText('All data will be lost') self.setIcon(QMessageBox.Warning) self.setStandardButtons(QMessageBox.No | QMessageBox.Yes) self.setDefaultButton(QMessageBox.No)
Mind that I use the
open
method and not the classicalexec_
method because the documentation for theQDialog.exec
method states:Note: Avoid using this function; instead, use open(). Unlike exec(), open() is asynchronous, and does not spin an additional event loop. This prevents a series of dangerous bugs from happening (e.g. deleting the dialog's parent while the dialog is open via exec()). When using open() you can connect to the finished() signal of QDialog to be notified when the dialog is closed.
How can I know when the user clicked on the "Yes" standard button? In the documentation or in the forums, all given exemples use the
exec_
method or a static declaration and it is very hard to find anything using theopen
method. I would like the solution to be as simple as possible because this dialog will be used many times in my program and I do not want to encumber the code.Thanks a lot and let me know if I can do anything!
-
@Kryzar
My opinion: save yourself the hassle! "Most people", myself included, will useQDialog::exec()
for a blocking dialog/messagebox. (Which is probably why you find most examples using it rather thanopen()
!) It's simple and it works. Just don't do the naughty things the docs tell you not to do!I could show you how to use then
open()
approach, but I really don't think it's worth the effort :) -
Hi,
You can use the buttonClicked signal for exemple.
-
@JonB
Thanks a lot for your insight, I really appreciate this kind of dialog (pin unintended). Genuine question: isn't the fact that the documentation advices you not to useexec_
a sufficient reason not to useexec_
? My opinion is that in computer sciences, tools work better when they are used the way they are designed to be used for. Also, the less people useexec_
, the more Qt developers are able to focus on improvingopen
and its poor documentation. Tho I agree that if people at Qt really wanted us Qt users to useopen
, they should have updated the documentation. -
@SGaist
Thanks a lot. This solution is indeed possible. However I would like the final code to be shorter and simpler because this dialog will be used in many places in the program and not all my colleagues instantiating it will be good at Qt and there is a risk of mistakes if the need to 1. create a slot 2. understand how standard buttons work.So what I wish I had (and I am sorry that I was not clear enough) is a boolean
yes
attribute to my classReallyWantToQuit
which tells if yes or no the user really wants to quit once the dialog is closed. If we useexec_
, this is really simple to do :class ReallyWantToQuit(QMessageBox): def __init__(self): super().__init__() self.setModal(True) self.setText('Do you really want to quit?') self.setInformativeText('All data will be lost') self.setIcon(QMessageBox.Warning) self.setStandardButtons(QMessageBox.No | QMessageBox.Yes) self.setDefaultButton(QMessageBox.No) self.button(QMessageBox.Yes).clicked.connect(self.__set_yes_True) @Slot() def __set_yes_True(self): self.__yes = True @property def yes(self): return self.__yes
and to use the dialog you can do
rwtq = ReallyWantToQuit() rwtq.exec_() if rwtq.yes: // Do what you need to quit
This does not work with
open
because unlikeexec_
, this function returns immediately. Do you know if it is possible to do this simply withopen
? If it is not or you feel it's not worth your time don't worry, this solution withexec_
is OK. -
@Kryzar said in QMessageBox clicked standard button with open (not exec_):
isn't the fact that the documentation advices you not to use
exec_
a sufficient reason not to useexec_
?Simple response: go out there and look at just how many apps/examples, both C++ & Python, use
QDialog::exec()
, and have done so for aeons. In just your kind of situation.If you want to pursue
open()
, that is fine and good. Just, in practice, you don't need to. -
@JonB
Honestly fair enough, thanks a lot.