Я вставил данные в подкласс QAbstractListModel
и отобразил их с QListView
и QTableView
изменения (удаление строки) отображаются в QListView
сразу, но в QTableView
, только если выбрано табличное представление
подгруппированная модель содержит метод setData
с self.dataChanged.emit(index, index)
внутри, поэтому он должен обновляться.
почему QTableView не обновляется сразу?
#!/usr/bin/env python
"""
minimum code to run a model view
"""
import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
class ViewModel(qtc.QAbstractListModel):
def __init__(self, input_data=None):
super().__init__()
self.input_data = input_data or []
# naming of rows ,columns static !!
def headerData(self, section, orientation, role):
if role == qtc.Qt.DisplayRole:
if orientation == qtc.Qt.Horizontal:
return "dude" # todo dynamic labeling
else:
return "leboswki" # todo dynamic labeling
def data(self, index, role):
if role == qtc.Qt.DisplayRole:
row = index.row() # == wie liste[row] der index
item = self.input_data[row]
return item
def rowCount(self, index): # parameter inside is needed !
return len(self.input_data)
def flags(self, index):
return qtc.Qt.ItemIsEditable | qtc.Qt.ItemIsSelectable | qtc.Qt.ItemIsEnabled
def setData(self, index, value, role):
if role == qtc.Qt.EditRole:
row = index.row()
if index.isValid():
self.input_data[row] = value
self.dataChanged.emit(index, index)
return True
else:
return False
def removeRows(self, position, rows, parent=qtc.QModelIndex()):
self.beginRemoveRows(parent, position, position + rows-1)
for i in range(rows):
value = self.input_data[position]
self.input_data.remove(value)
self.endRemoveRows()
return True
class MainWindow(qtw.QWidget):
def __init__(self):
super().__init__()
# View
list_view = qtw.QListView()
self.model = ViewModel(input_data=["text1", "text2", "text3", "text4"])
list_view.setModel(self.model)
table_view = qtw.QTableView()
table_view.setModel(self.model)
# widgets
self.deleate_row_button = qtw.QPushButton("deleate rows")
# layout
qvboxlayout = qtw.QVBoxLayout()
qvboxlayout.addWidget(list_view)
qvboxlayout.addWidget(table_view)
qvboxlayout.addWidget(self.deleate_row_button)
self.setLayout(qvboxlayout)
self.show()
# function
self.deleate_row_button.clicked.connect(lambda: self.model.removeRows(-1, 1))
if __name__ == '__main__':
app = qtw.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
1 ответ
Хотя в Python вы можете получить доступ к отрицательным индексам, но этого не происходит в Qt, вызывающем ошибку. Решение состоит в том, чтобы преобразовать отрицательные индексы в положительные. С другой стороны, не удаляйте строки по их значению (self.input_data.remove(value)
), поскольку, если бы у него было 2 строки с одинаковым текстом, могла бы возникнуть ошибка.
def rowCount(self, index=qtc.QModelIndex()):
return 0 if index.isValid() else len(self.input_data)
def removeRows(self, position, rows, parent=qtc.QModelIndex()):
position = (position + self.rowCount()) if position < 0 else position
start = position
end = position + rows - 1
self.beginRemoveRows(parent, start, end)
del self.input_data[start : end + 1]
self.endRemoveRows()
return True
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.