PyQt model/view: which type of model for programmatic changes?
I recently started rewriting an application and I'm trying to port it to model/view to reduce the number of kludges I have there.
So far I was able to succcessfully make a read-only model inheriting from QAbstractTableModel
. This model is something like this:
class MyModel(QtCore.QAbstractTableModel):
def __init__(self, data, parent=None):
super(MyModel, self).__init__(parent)
self.data = data
data
is a list that contains a number of objects. These are then accessed in the data() method:
def data(self, index, role):
# much stuff omitted for clarity
return QtCore.QVariant(self.data[index.column()].id)
Now this is fine if I work with a predefined data
element. But in fact data
changes programmatically (it expands when certain signals are received). How can I keep the model aware of this, so that then my view can also react to these changes?
I've been reading about re开发者_高级运维ad-write models but they also allow the user to edit and change things, while in my view I want things to be un-editable: in short, the model would need to be changed "behind the scenes" only, and the view adapt to that.
What is the best appproach in this case? Implement a read-write model with setData() and so on, or is there a simpler solution?
My logview application uses QAbstractTableModel
with a dynamic list - of log records, which increases dynamically as records are received across the network. You can download the source code and take a look at LogRecordModel
, which is a QAbstractTableModel
subclass, as is PropertySheetModel
. Both of these are read-only models.
It's a pretty simple application using Qt model/view APIs, so you should be able to adapt its techniques for your own application.
In fact, it's a bit more involved than you were probably hoping for. You have to let your view know when the table is being expanded or contracted. Because the view only updates items on a local basis when they are modified, it has to be informed when the table's shape changes.
So, you have to use the beginInsertRows() and beginRemoveRows() ( and their counterparts for columns ) when the table's shape changes.
See this and this for more information.
The setData method is called whenever the user changes an editable index.
Model/view programming can be a little difficult to get going, but it pays massive dividends (when done correctly) in terms of stability, interactivity, scalability, and re-usability.
Good luck!
精彩评论