Search code examples
pythonpyqtqt-designer

Configure Widgets in a Sub-Dialog in a pyqt Main Window


I have a GUI App with a Main Dialog and I added a button to it. Pushing the button adds another "dialog" where the user has to input some values. Both Ui-files are written with the QTDesigner and "dialog" has a "QtableWidget" with the object name "tableCo" I am not sure why I cannot change the properties of this tableWidget:

from PyQt4 import QtGui, QtCore, Qt  
from Main_Window import Ui_Dialog as Dlg
from dialog import Ui_MyDialog

class MainDialog(QtGui.QDialog, Dlg): 
    def __init__(self): 
        QtGui.QDialog.__init__(self) 
        self.setupUi(self)

        self.connect(self.buttonOK, 
                QtCore.SIGNAL("clicked()"), self.onOK) 
        self.connect(self.buttonAbbrechen, 
                QtCore.SIGNAL("clicked()"), self.onClose)

        self.connect(self.Button, 
                QtCore.SIGNAL("clicked()"), self.on_Button_clicked)

    def on_Button_clicked(self, checked=None):
        if checked==None: return
        dialog = QtGui.QDialog()
        dialog.ui = Ui_MyDialog()
        dialog.ui.setupUi(dialog)
        dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        dialog.exec_()


        some_list=["A","B","C"] 
        #a list in another python class from another script that changes so
        #the table properties have to be changed dynamically
        #here I just take a simple list as an example

        #the following two lines do not work (they work if tableCo is an 
        #object in the Main Dialog

        self.tableCo.setColumnCount(len(some_list))           
        self.tableCo.setHorizontalHeaderLabels(some_list)

    def onOK:
    ...
    def onClose:
    ...

If I push the button i see my "tableCo" widget, but the properties of the header have not changed, and after closing this sub-dialog I get the following error-message

Traceback (most recent call last):
  File "C:/gui.py", line 88, in on_Button_clicked
    self.tableCo.setColumnCount(len(some_list))
AttributeError: 'MainDialog' object has no attribute 'tableCo'

What do i have to change in my code to configure a Widget in a sub-Dialog?


Solution

  • There are two problems with the code in your on_Button_clicked.

    Firstly, you are attempting to call methods after the dialog has closed. When exec_ is called, the dialog enters a blocking loop until the user closes the dialog. When the dialog closes, the following lines will get executed, but the dialog will be immediately garbage-collected after that when the function returns.

    Secondly, you are attempting to access methods of the dialog using self, rather than via the local name dialog, which is why you are getting the AttributeError.

    You can fix these problems by creating a subclass for the second dialog in the same way that you have for your MainDialog class:

    class SubDialog(QtGui.QDialog, Ui_MyDialog): 
        def __init__(self, some_list, parent=None): 
            QtGui.QDialog.__init__(self, parent) 
            self.setupUi(self)
            self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
            self.tableCo.setColumnCount(len(some_list))           
            self.tableCo.setHorizontalHeaderLabels(some_list)
    
    class MainDialog(QtGui.QDialog, Dlg):  
        ...    
    
        def on_Button_clicked(self, checked=None):
            if checked is None: return
            dialog = SubQDialog(some_list)
            dialog.exec_()