Обновление данных QTableView
Столкнулся с проблемой не могу понять как заставить QTableView в pyqt5 отображать новые данные. Данные полностью меняются (целиком), после нажатия кнопки Update. Подскажите правильный подход.
Удаление и вставка по одной строке не подойдет, строк за одно обновление порядка 3-10к.
Ниже указана часть кода
import sys
from PyQt5 import Qt, QtWidgets, QtCore
from PyQt5.QtCore import Qt, QModelIndex
class TmodelCustom(QtCore.QAbstractTableModel):
def __init__(self, data=None, header=None):
QtCore.QAbstractTableModel.__init__(self)
self.load_data(data)
self.header = header
def load_data(self, data):
self.input_address = data[0]
self.input_numbers = data[1]
self.column_count = 2
self.row_count = len(self.input_numbers)
def rowCount(self, parent=QModelIndex()):
return self.row_count
def columnCount(self, parent=QModelIndex()):
return self.column_count
def headerData(self, section, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.header[section])
return QtCore.QVariant()
def data(self, index, role=Qt.DisplayRole):
column = index.column()
row = index.row()
if role == Qt.DisplayRole:
if column == 0:
return "{}".format(self.input_address[row])
elif column == 1:
return "{}".format(self.input_numbers[row])
return None
class Counter(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Counter, self).__init__(parent)
self.setWindowFlags(QtCore.Qt.Window)
QtWidgets.QMainWindow.__init__(self)
header = ["ADDRESS", "NUMBER"]
df = [['1', '2', '6'], ['3', '4', '5']]
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
grid_layout = QtWidgets.QGridLayout()
central_widget.setLayout(grid_layout)
self.model = TmodelCustom(data=df, header=header)
self.table = QtWidgets.QTableView(self)
self.table.setModel(self.model)
update_button = QtWidgets.QPushButton("Update")
update_button.clicked.connect(self.on_update_button)
horisontal_layout = QtWidgets.QHBoxLayout()
horisontal_layout.addStretch(1)
horisontal_layout.addWidget(update_button)
horisontal_layout.setAlignment(QtCore.Qt.AlignRight)
grid_layout.addLayout(horisontal_layout, 0, 0)
grid_layout.addWidget(self.table, 1, 0)
def on_update_button(self):
pass
if __name__ == "__main__":
application = QtWidgets.QApplication([])
window = Counter()
window.setWindowTitle("Counter")
window.setMinimumSize(480, 380)
window.show()
sys.exit(application.exec_())
Заранее благодарю Вас!
Ответы (2 шт):
Надо сказать таблице, что данные в модели изменились. Делается это при помощи методов, которые объявлены в классе QAbstractItemModel и чье имя начинается с begin ("начинающие транзакцию") и парные им end ("закрывающие транзакцию"), и/или сигнала QAbstractItemModel::dataChanged.
В частности, в вашем случае, видимо, подходят пары функций QAbstractItemModel.beginResetModel и QAbstractItemModel.endResetModel.
def load_data(self, data):
self.beginResetModel()
self.input_address = data[0]
self.input_numbers = data[1]
self.column_count = 2
self.row_count = len(self.input_numbers)
self.endResetModel()
Теперь, соответствующий вызов функции обновления модели, с соответствующими аргументами должен обновить таблицу:
def on_update_button(self):
self.model.load_data(...)
я предложу вариант с использованием модели QStandardItemModel
import sys
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtCore import Qt
class Counter(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Counter, self).__init__(parent)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
self.table = QtWidgets.QTableView(self)
self.model = QtGui.QStandardItemModel()
self.model.setColumnCount(2)
self.model.setRowCount(0)
self.model.setHorizontalHeaderLabels(['ADDRESS', 'NUMBER',])
self.table.setModel(self.model)
self.label = QtWidgets.QLabel("Укажите количество строк:")
self.lineEdit = QtWidgets.QLineEdit("7")
update_button = QtWidgets.QPushButton("Update")
update_button.clicked.connect(self.on_update_button)
self.iter = None
self.timer = QtCore.QTimer(interval=200, timeout=self.add_row)
grid_layout = QtWidgets.QGridLayout(central_widget)
grid_layout.addWidget(self.label, 0, 0)
grid_layout.addWidget(self.lineEdit, 0, 1, 1, 2)
grid_layout.addWidget(update_button, 0, 3)
grid_layout.addWidget(self.table, 1, 0, 1, 4)
def on_update_button(self):
try:
rows = int(self.lineEdit.text())
except ValueError:
print("Введенное значение должно быть целым числом.")
else:
if rows > 0:
self.model.setRowCount(0)
self.iter = iter(range(rows))
self.add_row()
self.timer.start()
else:
print("Введенное значение должно быть положительным целым числом.")
def add_row(self):
try:
i = next(self.iter)
except StopIteration:
self.iter = None
self.timer.stop()
else:
item1 = QtGui.QStandardItem("item" + str(i))
item1.setTextAlignment(QtCore.Qt.AlignCenter)
item2 = QtGui.QStandardItem("item" + str(i))
item2.setTextAlignment(QtCore.Qt.AlignCenter)
self.model.appendRow([item1, item2])
if __name__ == "__main__":
application = QtWidgets.QApplication([])
window = Counter()
window.setWindowTitle("Counter")
window.setMinimumSize(480, 380)
window.show()
sys.exit(application.exec_())
