I am trying to understand how one would choose whether to use a QAbstractListModel or a QObject with a QQmlListProperty.
Given that the QQmlListProperty handles the "roles" functionality that would have to be written using the QAbstractListModel, it seems like the less tedious route.
I can't tell if most people suggest using QAbstractListModel simply because it has been around longer or if it is the better choice for some reason.
Nor have I been able to find any discussion of the trade-offs between the two options. This question was brought up during a Qt Developer Days talk discussing QAbstractListModel, but the answer was along the lines of "that would also work".
A model implementation will generally be more efficient to work with a view. When you expose a "dumb list" to use a model, every time the model changes the whole view is reconstructed, whereas with a model only the changes are updated. If you have a lot of items there will be tangible performance overhead.
You could use a list for a model, and you could use a model for a list, but when you want optimal performance, you should use a list for a list, and a model for a model.
Related
I'm using Qt creator to write c++ GUI application. I want to have a list to show the some guides to user and prefer to have a list with Scroll Bar. what widget can I use to this?
For displaying lists, trees and tables, Qt has a set of Model/View classes.
In model/view, a subclass of QAbstractItemModel provides the data, which is then displayed by a QAbstractItemView. Models can be "stacked" for rather flexible filtering, sorting and mapping of data (see e.g. QSortFilterProxyModel).
There's basically now three ways to use them, of varying complexity, power and scalability:
So if you want full flexibility or have a large number of list entries (say, in the thousands), implement a QAbstractListModel with a QListView. While this is the most powerful solution, it's also the most complex one, and implementing a correct and efficient model has some pitfalls.
A simpler way would be to use QStandardItemModel (or for an even simpler list of just strings, QStringListModel) and set that as model of a QListView. That might be far less daunting for a beginner, compared with having to implement your own models. It's not the most scalable version, but if you display e.g. 50 items, that just doesn't matter.
You can still combine it with sorting and filtering via proxy models.
Then, the third and most simple way is to display a list is to use QListWidget. It's a subclass of QListView that allows you to pass in the list items via QListWidgetItem, similar to QStandardItemModel. It basically "merges" the model functionality into the view class so that you don't have to touch models at all. While this is the simplest way, it's also the most inflexible one: You cannot use sort/filter proxy models when using a QListWidget.
To get started with Model/View, especially to people who are used to manage item-based lists, I recommend (2) and then move up to (1). If you just want a simple and immutable list of a couple items, (3) might as well do. If you find out later that you need sort/filter functionality, converting (3) into (2) later is usually rather easy, while converting (3) to (1) is a far more intrusive change.
I want to implement in my program a tree with nested sub-levels, and I'm looking for which of those two kind(View/Widget) is best suited for my goal.
I have a list of days with task that are either done/missed/failed, each task has a count of how many times it was done/missed/failed and lastly a score for that day.
I want to display them like so:
I made this example in QtCreator using a QTreeWidget, but I'm worried that it would be hard to modify the elements since they are stored somewhere else.
Are my worries rational and should I go to the model/view structure, or can I easily get going with the QTreeWidget? The tree will be logging the task and thus will be constantly changing. Elements will only be added to it, not removed. And the days will be sorted from highest-lowest(day 2 is first, then day 1)
If your data is stored in a database model or if you want to have a single data model and show it in some views in different ways, then you are definitely better to go with QTreeView.
But QTreeWidget has it's internal model in some way along with the methods to deal with model in context of indexes. In general if you just want something that is simple to work, you can use the widget way.
But the Model/View approach is more general and flexible IMO. You can create your own subclasses of model and view which enables you to do whatever you like.
I'm reading up on the latest version of Qt, and it seems the Model/View/(Delegate) pattern is what's being pushed. It should be conceivable then to completely wire up the views without writing a single model, at least for the purpose of specing out how it looks. Is this the advised approach?
Also, where are the event wirings supposed to be placed? I assume that signals are coordinated by the MainWindow code?
You will need dummy models of course, made using existing Qt model classes. Looking at empty views is somewhat unhelpful, since you can't check out the primary delegates for the underlying model. Without any data, about the only delegates you can check out are the ones used in the headers, IIRC.
There are no event "wirings" on the view side of things, except for providing programmatic means of interacting with the view. The models may need a lot of interaction, depending on what's being modeled
Conceptually, you may have just one model that represents the data in your application, but it'd be a lot of spaghetti to expose various aspects of that model to the specialized views. You may then use view-models as adapters: they'd take the big model and expose a targeted slice of it, making it easier to consume by views. That's the pattern widely used in .net WPF.
I am not a professional application developer so am probably not as familiar with the model/view design pattern as I should be. Nonetheless, I am trying to use it in a hobby app and failing miserably. The primary problem I am having is that the data I am trying to display and modify is not easily represented with an extension of QAbstractItemModel.
The data I am trying to encapsulate is essentially a growable/shrinkable, mutable list of integers. Should I abandon the model/view pattern for data like this? It seems more appropriate when the "dimensions" of the data are fixed. If not, is there an example of an implementation that I could take a gander at, or a good book that I should pick up?
Regards.
I would look at QAbstractListModel. It sounds like a more relevant model than the basic QAbstractItemModel.
There is also a rather different view of that model in the example: Puzzle
If you need a higher level look at Model/View, check out this.
QAbstractItemModel is just one, admittedly very limited way of implementing the Model/View design pattern. If you see that your situation doesn't fit it neatly don't bother working too hard to force it.
A better approach for you would probably be to just pull your own Model class with your own View classes and abandon QAbstractItemModel. There is more to this design pattern than the weird flavor implemented in QT and that flavour only works well for very particular applications.
I suggest you read about it some more and design your own Model-View setup. Your class design is very likely to be cleaner and better understood if you pull your own.
I'm a (Py)Qt newbie, porting C# GUI code to Qt for a couple of days now. One question that I keep asking myself is why are QAbstractItemModel subclasses required to supply a parent() method, and why are they required to supply, in the resulting QModelIndex, the row of a child in the parent?
This requirement forces me to add another layer over my tree data (because I don't want to call indexOf(item) in parent(), it wouldn't be very efficient) that remembers row indexes.
I ask this because it's the first time I see a model based view require this. For example, NSOutlineViewDataSource in Cocoa doesn't require this.
Trolltech devs are smart people, so I'm sure there's a good reason for this, I just want to know what reason.
The quick answer is, "they thought it best at the time." The Qt developers are people just like you and me -- they aren't perfect and they do make mistakes. They have learned from that experience and the result is in the works in the form of Itemviews-NG.
In their own words from the link above:
Let’s just say that there is room for improvement, lots of room!
By providing a parent that contains a row and column index, they provide one possible way to implement trees and support navigation. They could just as easily have used a more obvious graph implementation.
The requirement is primarily to support trees. I couldn't tell you the reason, since I'm not a Qt dev... I only use the stuff. However, if you aren't doing trees, you could probably use one of the more-tuned model classes and not have to deal with the overhead of supplying a parent. I believe that both QAbstractListModel and QAbstractTableModel handle the parent portion themselves, leaving you free to just worry about the data you want.
For trees, I suspect that one of the reasons they need the parent is that they try to keep to only asking for the information they need to draw. Without knowing all of the items in a tree (if it wasn't expanded, for example), it becomes much harder to provide an absolute position of a given item in a tree.
As for the quandry of using indexOf(item) in the parent function, have you considered using QModelIndex's internalId or internalPointer? I'm assuming they are available in PyQt... they can be used by your model to track things about the index. You might be able to use that to shortcut the effort of finding the parent's index.