Я хочу динамически создавать и заполнять QTableWidgets на PyQt4.
Моя цель - отображать разные наборы данных в разделенных таблицах (размещенных на разных вкладках в QTabWidget). Имена наборов данных и их количество непредсказуемы, я не могу предварительно создать таблицы / вкладки в Qt Designer.
Я не нашел других сообщений по этому поводу, кроме воспроизведения существующих виджетов (в основном QPushButtons, но прошу прощения, если эта проблема уже возникла.
Как вы можете видеть на картинке ниже, я смог создать вкладки, дать им имя динамически (здесь, скажем, tab_1, tab_2 и tab_3) и добавить к ним виджеты.
Однако, когда я пытаюсь заполнить таблицы, оказывается, что я заполняю одну и ту же таблицу на разных вкладках (таблицы на каждой вкладке называются одним и тем же QTableWidget).
Функция:
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)
Проблема связана с этими двумя строками, поскольку имя, связанное с QtGui.QTableWidget(), - это self.Table_1, а не его значение.
self.Table_1 = "Table_%s" % str(i) #Table_1, Table_2, Table_3, ...
self.Table_1 = QtGui.QTableWidget()
Я также пробовал setattr, но безуспешно, таблицы создаются, но я получаю сообщение об ошибке, когда вызываю self.Table_1 для заполнения.
Уважаемые Python Gurus, заранее благодарю вас за вашу помощь!
что такое populateTable_1? есть populateTable_2?






Если вы хотите установить свойства с динамическим именем, вы должны использовать 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)
если есть метод для n-й вкладки, существует также метод populateTable_n, тогда вы должны использовать getattr():
getattr(self, "populateTable_{}".format(i))()
Благодарю за ваш ответ! Я внес ваши изменения, но в таблицах по-прежнему отображаются те же данные. Я использую один метод для заполнения всех таблиц, он собирает необходимые данные во вложенном словаре для каждой таблицы.
@AlanB. Если вы предоставите минимальный воспроизводимый пример, я смогу помочь вам правильно, так как могу протестировать ваш код.
@AlanB. пожалуйста, не помещайте код в комментарии, не торопитесь и предоставляйте минимальный воспроизводимый пример, попробуйте помочь сейчас, только пустая трата времени, когда вы предоставите MCVE, я буду рад помочь
Извините, я удалил свой комментарий.
Решил проблему вашим методом @eyllanesc, неправильно использовал getattr(). Спасибо за помощь!
Вы всегда перезаписываете атрибут Table_1 новым экземпляром QtGui.QTableWidget. Если вам нужно несколько таблиц, у вас есть несколько путей. Либо у вас может быть несколько предложенных атрибутов, таких как @eyllanesc, либо вы можете просто создать «контейнер» - или list в моем примере - таблиц для той же цели.
self.Table = []
self.label = []
for i,s in enumerate(dataSets):
tab_name = str(s)
layout = QVBoxLayout()
self.label.append( QLabel() )
self.label[i].setText(u"Data set:")
# Up to here, it looks like everything works fine
self.Table.append( QtGui.QTableWidget() )
self.Table[i].setMaximumSize(QtCore.QSize(16777215, 150))
self.Table[i].setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.Table[i].setObjectName(_fromUtf8(tab_name)) # Why not use the name of the "dataSet"?
self.Table[i].setColumnCount(0)
self.Table[i].setRowCount(0)
layout.addSpacing(20)
layout.addWidget(self.label[i])
layout.addWidget(self.Table[i])
self.populateTable(i) # You must change the input arguments of this method and provide
# the access to the elements within the list inside of this method,
# in order to use it like here.
self.tabWidget.setLayout(layout)
Я также удалил все строки, которые не влияют на сами таблицы.
Спасибо за вашу помощь, метод eyllanesc кажется мне более простым, но я посмотрю на ваш, если я не смогу заставить его работать должным образом.
что за сообщение об ошибке?