Search code examples
pythonpyqtpyqt4qtablewidget

Dynamically create/populate QTableWidgets in PyQt4


I want to dynamically create and populate QTableWidgets on PyQt4.

My goal is to display different sets of data on separated tables (placed on different tabs in a QTabWidget). The data sets names and their number are not predictable, I cannot pre-create the tables/tabs in Qt Designer.

I did not find any other post about this matter, except for reproducing existing widgets (mostly QPushButtons but I apologize if this problem has already been brought up.

As you can see on the picture below, I was able to create the tabs, give them a name dynamically (here let’s say tab_1, tab_2 and tab_3) and add widgets to them.

However, when I try to populate the tables it turns out that I am populating the same table in my different tabs (the tables in each tab are referred as the same QTableWidget).

Function:

for i,s in enumerate(dataSets):

    tab_name = str(s)
    tab = QWidget()

    self.tabWidget.addTab(tab, tab_name)     

    layout = QVBoxLayout()
    label_1=QLabel()
    spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)

    label_1.setText(u"Data set:")

    # Up to here, it looks like everything works fine

    self.Table_1="Table_%s" % str(i)     #Table_1, Table_2, Table_3, ...

    self.Table_1 = QtGui.QTableWidget()
    self.Table_1.setMaximumSize(QtCore.QSize(16777215, 150))
    self.Table_1.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
    self.Table_1.setObjectName(_fromUtf8(str(self.Table_1)))
    self.Table_1.setColumnCount(0)
    self.Table_1.setRowCount(0)

    layout.addSpacing(20)
    layout.addWidget(label_1)
    layout.addWidget(self.Table_1)
    self.populateTable_1()

self.tabWidget.setLayout(layout)

The problem comes from these two lines as the name associated with the QtGui.QTableWidget() is self.Table_1 and not its value.

self.Table_1="Table_%s" % str(i)     #Table_1, Table_2, Table_3, ...

self.Table_1 = QtGui.QTableWidget()

I tried setattr as well, but without any success, the tables are created but I get an error when I call self.Table_1 to populate it.

Dear Python Gurus, I thank you in advance for your help!


Solution

  • If you want to set properties with a dynamic name you must use setattr():

    for i,s in enumerate(dataSets):
        tab_name = str(s)
    
        tab = QWidget()
        layout = QVBoxLayout(tab)
    
        label=QLabel(u"Data set:")
    
        tableName = "Table_{}".format(i)     #Table_1, Table_2, Table_3, ...
        table = QtGui.QTableWidget(0, 0)
        table.setMaximumSize(QtCore.QSize(16777215, 150))
        table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        table.setObjectName(_fromUtf8(str(tableName)))
        layout.addSpacing(20)
        layout.addWidget(label)
        layout.addWidget(table)
    
        setattr(tableName, table)
        self.tabWidget.addTab(tab, tab_name)
    

    if there is a method for tab n-th there is also a method populateTable_n then you must use getattr():

    getattr(self, "populateTable_{}".format(i))()