我可以找到一些如何在标准视图中使用标准模型的例子。
http://doc.qt.io/qt-5/modelview.html
http://doc.qt.io/qt-5/qtwidgets-itemviews-simplewidgetmapper-example.html
但我找不到一个如何使用QAbstractModel
制作我自己的model
并在我自己view/widget
上使用它的示例。
更新模型后,立场视图将更新,但不会更新我自己的视图。
完整代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import (QWidget, QLabel, QDataWidgetMapper,
QLineEdit, QApplication, QGridLayout)
from PyQt5.QtCore import QAbstractListModel, Qt
from PyQt5.QtWidgets import QListView
class Window(QWidget):
def __init__(self, model, parent=None):
super(Window, self).__init__(parent)
self.model = model
# Set up the widgets.
nameLabel = QLabel("Na&me:")
nameEdit = QLineEdit()
# Set up the mapper.
self.mapper = QDataWidgetMapper(self)
self.mapper.setModel(self.model)
self.mapper.addMapping(nameEdit, 0)
layout = QGridLayout()
layout.addWidget(nameLabel, 0, 0, 1, 1)
layout.addWidget(nameEdit, 0, 1, 1, 1)
self.setLayout(layout)
self.mapper.toFirst()
class MyModel(QAbstractListModel):
def __init__(self, status=[], parent=None):
super().__init__(parent)
self.status = status
def rowCount(self, index_parent=None, *args, **kwargs):
return len(self.status)
def data(self, index, role=Qt.DisplayRole, parent=None):
if not index.isValid():
return None
row = index.row()
if row == 0:
print(index)
if role == Qt.DisplayRole:
return self.status[row]
elif role == Qt.EditRole: # if it's editing mode, return value for editing
return self.status[row]
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsEditable
def setData(self, index, value='', role=Qt.EditRole):
row = index.row()
if role == Qt.EditRole:
self.status[row] = value
self.dataChanged.emit(index, index) # inform the other view to request new data
return True
else:
return False
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
myModel_on_mywindow = MyModel([1, 2, 3])
mywindow = Window(myModel_on_mywindow)
mywindow.setWindowTitle('myModel_on_mywindow')
mywindow.show()
myModel_on_mywindow.status[0] = 2
myModel_on_qlistview = MyModel([1, 2, 3])
qlistview = QListView()
qlistview.show()
qlistview.setModel(myModel_on_qlistview)
qlistview.setWindowTitle('myModel_on_qlistview')
myModel_on_qlistview.status[0] = 2
sys.exit(app.exec_())
答案 0 :(得分:3)
您的自定义模型需要覆盖抽象模型的某些函数,具体取决于您子类的哪一个。这是子类化QAbstractListModel的一个小例子。您可以在Qt文档中了解更多相关信息:QAbstractListModel Details
class MyModel(QAbstractListModel):
def __init__(parent=None):
QAbstractListModel.__init__(parent)
self.content = [] # holds the data, you want to present
def rowCount(index):
return len(self.content)
# This defines what the view should present at given index
def data(index, role):
if index.isValid() and role == Qt.DisplayRole):
dataElement = self.content[index.row()]
if index.colum() == 0:
return dataElement.someBoolField
if index.colum() == 1:
return dataElement.someIntField
# ...
}
return QVariant() # this is like returning nothing
}
# If your items should be editable. Automatically called, when user changes the item.
def setData(index, value, role):
if index.isValid():
dataElement = self.content[index.row()].get()
if index.column() == 0:
return dataElement.tryToSetBoolField(value.toBool())
if index.column() == 1:
return dataElement.tryToSetIntField(value.toInt())
# ...
}
return True
}
};
# connecting your view with your model
model = MyModel()
myView = QTreeView() # or something else
myView.setModel(model)
修改强>
要在将自定义模型与QDataMapper结合使用时更新视图,请在更改模型后调用setCurrentIndex(changedIndex)或其包装器,如下所示:
myModel_on_mywindow.status[0] = 2
myModel.mapper.toFirst()
QDataMapper上的Qt文档在详细说明中提到了这一点:
导航函数toFirst(),toNext(),toPrevious(),toLast()和setCurrentIndex()可用于在模型中导航并使用模型中的内容更新小部件。