Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt QDialog - returning a value and closing from dialog

I'm working on a user interface in PyQt, and I'm running into a few problems trying to use QDialog. Essentially I have a main widget and a sub-widget, saved in separate .py files; I would like the sub-widget to open when I click a certain button in the main widget. This seems to be opening fine.

The issue comes with returning and closing. I have a "submit" button on my sub-widget - when the user clicks this button, I would like to return a value (a dictionary made from their input) to the main widget, and close the sub-widget. I can't seem to do either of these things with the code I have right now.

Applicable bits of code in the main widget (can add more to make it self-contained if the problem isn't obvious):

import SGROIWidget_ui

def retranslateUi(self, ROIGUI):
    #ShowGroupROI is a push-button
    self.ShowGroupROI.clicked.connect(self.ShowGroupROIFunction)

def ShowGroupROIFunction(self):
    dialog = QDialog()
    dialog.ui = SGROIWidget_ui.Ui_ShowGroupWidget()
    dialog.ui.setupUi(dialog)
    dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    if dialog.exec_():
        roiGroups=dialog.Submitclose()
        print(roiGroups)
        dialog.accept()

I never seem to hit the code after the if-statement.

The applicable code from my sub-widget (will include a bit more here):

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_ShowGroupWidget(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setupUi(self)

    def setupUi(self, ShowGroupWidget):
        #sets up Submit button

    def retranslateUi(self, ShowGroupWidget):
        self.Submit.clicked.connect(self.Submitclose)

     def Submitclose(self):
        roiGroups={}
        #roiGroups gets set up here as a dictionary
        #It prints nicely from here so I know it's not the issue

        return roiGroups 
        #I don't know if I can just do a return statement like this?
        self.close()*

*I have tried ex.close() here as well but ex is not recognized when this widget is run as a dialog. It doesn't seem like it should get to this line because of the return statement, but I don't know how else to close this widget after the user hits "submit". Or should the dialog.accept() in my main widget handle that?

One last thing - do I need this in my sub-widget at all, since it's being run through my main widget instead?

if __name__=='__main__':
    app=QtGui.QApplication(sys.argv)
    ex=Ui_ShowGroupWidget()
    ex.show()
    sys.exit(app.exec_())

Thanks in advance! I am pretty new to PyQt so hopefully this is somewhat legible.

like image 581
Emily C Avatar asked Feb 24 '15 21:02

Emily C


People also ask

What is QDialog in PyQt5?

A QDialog widget presents a top level window mostly used to collect response from the user. It can be configured to be Modal (where it blocks its parent window) or Modeless (the dialog window can be bypassed). PyQt API has a number of preconfigured Dialog widgets such as InputDialog, FileDialog, FontDialog, etc.

What is QWidget in PyQt5?

The QWidget widget is the base class of all user interface objects in PyQt5. We provide the default constructor for QWidget . The default constructor has no parent. A widget with no parent is called a window.

How do I close PyQt app?

The simplest way to close a window is to click the right (Windows) or left (macOS) 'X' button on the title bar.


1 Answers

There are a few issues. The if dialog.exec_(): line will only succeed if the dialog is exited with accept(). Are you working with QDesigner? If so, check this for a different way of working. If Ui_ShowGroupWidget just contain code you write, you should make it inherit QDialog instead of QWidget. Then, instead of closing it with self.close(), you close it with self.accept(). You can't return a diccionary, but you can save it as an object attribute. Once the dialog.exec_() returns, you can access that attribute.

It could be something like this:

def ShowGroupROIFunction(self):
    dialog = SGROIWidget_ui.Ui_ShowGroupWidget()
    if dialog.exec_():
        print(dialog.roiGroups)

The other one:

...

class Ui_ShowGroupWidget(QtGui.QDialog):
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.setupUi(self)
        self.roiGroups = {}
        self.Submit.clicked.connect(self.submitclose)

    def setupUi(self, ShowGroupWidget):
        #sets up Submit button

    def submitclose(self):
        #do whatever you need with self.roiGroups    
        self.accept()

At last, if __name__=='__main__': means "if this file is executed as the main file, then..", which is not the case as you are including and using it from another one. So you can remove it, however, the idea is that you can run python ui_mywidget.py in order to test it or see the Ui defined on that file

like image 86
Smasho Avatar answered Oct 26 '22 23:10

Smasho