Python Forum

Full Version: SOLVED QMessageBox: can't get QMessageBox.Yes to work
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
G'day mates,
For a project, I need to return Gui notifications/questions to the user from several different modules. Rather than write an individual QMessageBox each time, I wrote a small module that is imported and called as needed.

I'm having a bit of trouble with that module when asking the user for a Yes/No choice. Every time I run it, I'm getting a response of "no" no matter of the user presses the Yes or the No button. I've written a small example to demonstrate what I'm seeing:
https://gitlab.com/Fred-Barclay/SimpleQt

Output when running and pressing the "Yes" button:
$ python3 simple.py
askQ
<PyQt5.QtWidgets.QMessageBox object at 0x7f1f6eca0318>
NO
no
And the offending code (in notifiCat.py):
def askQuestion(self, title, msg): 

    '''Ask a question with a yes/no dialog.'''
    ask = QMessageBox(self) 
    ask.setWindowTitle(title) 
    ask.setText(msg) 
    ask.setStandardButtons(QMessageBox.Yes | QMessageBox.No) 
    ask.setDefaultButton(QMessageBox.Yes) 
    # ask.addButton(QPushButton('Yes'), QMessageBox.YesRole) 
    print(str(ask)) 
 
 
    if ask == QMessageBox.Yes: 
        print('YES') 
        ans = 'yes' 
    else: 
        print('NO') 
        ans = 'no' 
    ask.exec() 
    ask.setModal(0) 
    ask.show() 
    print(ans)
Even though I pressed "yes", it's returning "no" as my choice. I can understand why "ans" is set as "no" because of the else statement. What I can't understand is why my first if statement is failing. Every example I've seen online is very similar and always tests if the button press == QMessageBox.Yes. But for some reason, my code isn't registering this button press. Can someone help me figure out what I'm doing wrong?

This is on either Windows 7 (python 3.6) or Debian Sid (python 3.5), with PyQt 5.7.

Thanks!
Fred

Solved!
It turns out that the correct test is if ask.exec_() == QMessageBox.Yes, like so:
def askQuestion(self, title, msg):
    '''Ask a question with a yes/no dialog.'''
   if self == 'noself':
       self = QWidget()
   ask = QMessageBox(self)
   ask.setWindowTitle(title)
   ask.setText(msg)
   ask.setIcon(QMessageBox.Question)
   ask.setDefaultButton(QMessageBox.Yes)
   ask.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
   ask.setWindowModality(0)
   ask.activateWindow()
   ask.show()
   retval = ask.exec_()


   if retval == QMessageBox.Yes:
       ans = 'yes'
   else:
       ans = 'no'

   return(ans)
I also have to use both ask.show() and ask.exec_(). If I only use ask.show(), the code doesn't wait for a button press, and ans is always set as 'no' (I'm not entirely sure why this happens). But if I only use ask.exec_(), the window will always be modal, which I don't want. Combining them gives a non-modal window that actually waits on the user's input. :)

I forgot to mention in my first post, the reason I'm having to do it this way is because I need the dialog window to be non-modal. If having a modal window were an option, using QMessageBox.question would have been the best way to do this.