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.
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.
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.
The simplest way to close a window is to click the right (Windows) or left (macOS) 'X' button on the title bar.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With