Dave Lewis
Dave Lewis

Reputation: 124

PyQt4 - closing a dialog window, exec_() not working

Trying to build a user interface using PyQt4. Got a dialog window that pops up, and I want it to do something then close, when 'Ok' is pressed. Unfortunately, I can't seem to get it working - tried all sorts of combinations of Dialog.exec_(), Dialog.close(), self.exec_(), self.close(), emitting an 'accepted' signal to Dialog.accept, etc. So far, nothing has worked, and I'm not quite sure why. Here's the code for it:

Dialog window initialised as such;

def begin_grab(self):
    self.GrabIm=qtg.QDialog(self)
    self.GrabIm.ui=Ui_Dialog()
    self.GrabIm.ui.setupUi(self.GrabIm)
    self.GrabIm.show()

Dialog window;

class Ui_Dialog(object):

    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        ...
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), self.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def accept(self):
        if self.radioButton.isChecked()==True: #assume it is true
            #Call continuous grabber
            print "Grabbing continuously"
            Dialog.exec_() #Close it here
        else:
            #Call trigger server
            print "Grabbing triggered"
            self.exec_()

The main thing that keeps happening is either a message saying 'Dialog' is an unknown variable, in the accept() function, or if I use self.exec_() or similar it says exec_() is not a known attribute. If I try doing accept(self, Dialog), and put self.accept(Dialog) in the connect statement, it also crashes.

Any and all help would be appreciated.

Upvotes: 1

Views: 13653

Answers (2)

Avaris
Avaris

Reputation: 36725

You are doing it pretty wrong. You shouldn't modify the Qt Designer generated code (Ui_Dialog). You should subclass QDialog and define the accept there:

class MyDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(MyDialog, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        # use new style signals
        self.ui.buttonBox.accepted.connect(self.accept)
        self.ui.buttonBox.rejected.connect(self.reject)

    def accept(self):
        if self.ui.radioButton.isChecked(): # no need to do ==True
            #Call continuous grabber
            print "Grabbing continuously"
        else:
            #Call trigger server
            print "Grabbing triggered"
        super(MyDialog, self).accept()  # call the accept method of QDialog. 
                                           # super is needed 
                                           # since we just override the accept method

Then you initialize it as:

def begin_grab(self):
    self.GrabIm=MyDialog(self)
    self.GrabIm.exec_()  # exec_() for modal dialog
                           # show() for non-modal dialog

But looking at your code, I wouldn't do it that way. Let the dialog return with accept/reject and then do your conditional stuff in the caller (i.e. Main window):

class MyDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        super(MyDialog, self).__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        # use new style signals
        self.ui.buttonBox.accepted.connect(self.accept)
        self.ui.buttonBox.rejected.connect(self.reject)

and the caller code:

def begin_grab(self):
    self.GrabIm=MyDialog(self)
    if self.GrabIm.exec_():  # this will be True if dialog is 'accept'ed, False otherwise
        if self.GrabIm.ui.radioButton.isChecked():
            #Call continuous grabber
            print "Grabbing continuously"
        else:
            #Call trigger server
            print "Grabbing triggered"

Upvotes: 10

Achayan
Achayan

Reputation: 5895

You can re implement closeEvent which will help you to do some process before Dialog exit

def closeEvent(self,event):
   print "I am here"
   event.accept()

Upvotes: 0

Related Questions