Thank you for your clarification on the behaviour of QTableView.
Your description implies there should actually be 3 queries against the data, then. I only see 2. However, I admit I would need more time to be sure.
Let me see if I have understood the behaviour of setSortingEnabled() & sortByColumn():
setSortingEnabled() is what makes the View show sort indicators on column headers and allow clicking. It also executes a data fetch query, passing whatever (if anything) is currently defined as the sort order (from sortByColumn()) into an ORDER BY.
sortByColumn() determines the ORDER BY. It too executes a data fetch.
(Please correct me if I am wrong.) Now, after (just, i.e. no sortByColumn() yet) a setSortingEnabled() I will see the sort indicator in some direction on some column. I am guessing this would be Ascending on column #0 initially(?) However, the query it issues has no ORDER BY at all, so by definition the rows are in indeterminate order. This seems simply inconsistent to me.
What I would have expected/hoped is that setSortingEnabled() would have passed an ORDER BY col0 ASC if that is how the data is supposed to be sorted to correspond to the initial sort indicator state, and/or an optional parameter to allow specification of the initial sort order desired in the View and to be passed in the initial query --- in effect, combining the setSortingEnabled() with an initial sortByColumn(). Or even, as you say, an equivalent of QSqlTableModel.setSort(). As it stands it seems you must fetch the data twice simply to correspond to the View's initial state.
I have inherited 32K lines of code which uses every kind of Qt SQL/model/view architecture all over the place, it's a mess. I will indeed investigate QSortFilterProxyModel. I don't mind which code I use to achieve it, I just don't expect any necessity to fetch the data multiple times for the initial situation.
Thank you for your suggestion. I think it's what I'll eventually settle for, fairly easy to indeed, using just one SQL query.
Although, I'm starting to think ... wouldn't my original aim be easier to fulfil using TreeWidget and not TreeView?
Hello guys. Thanks for your answerS.
The "error" was simple, stupid. In fact the _manageOrderedTable is an instance of a class called ManageOrderedTable which inherits from QTableWidget.
In this class, there's a method called fillAll and I called setColumnCount() from there. Bad idea.
When I call this method from upon the for loop, everything is fine. I don't understand why.
I could understand if setColumnCount() were called too late, but in this case I should have a segfault, trying to call a cell that doesn't exist.
Well, I don't really understand why but now it works...
@michalos I'm not sure if I can help you but seems like model test code works for me.
What I did:
Added modeltest.h and cpp into my project
Added "testlib" into "QT" section of project file
Added this to modeltest.h:
#define qVariantCanConvert(_type_, _var_) _var_.canConvert(QMetaType::_type_)
Changed expressions like "qVariantCanConvert<QString> ( variant)" to "qVariantCanConvert(QString, variant)" in modeltest.h
And... my sample model failed to pass the test of course :D
My second and main question is then : how to implement correct drag and drop operations with custom QStandardItem which needs to own custom data ?
With the standard item widgets/models you can't drag-n-drop custom item roles.
This makes sense, since the model doesn't know which UserRole+ was set.
It would need to iterate all possible item-role values when creating the drop-data.
The only solution i see is to create your own custom model and reimplement the needed drag-n-drop methods. This also give you full control over your data structure storing the data inside the model.
This is more work, but you will learn a lot and gain some performance (by avoiding the standard-item classes)
each index can max only have 1 delegate. Thus you need to merge the code into your own delegate.
Since you also receive a QModelIndex in the most methods of the delegate you need to check the column there.
//Returns the source model index (In my case it was QFileSystemModel)
//filemodel is My QFileSystem Model.
I don't know if there are any Qt models that support SQL for trees. I think they were all built for tables so you might have to build one yourself.
Have you checked out the Simple Tree Model example? I found it pretty helpful: http://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html . Also, if you find it easier, you can use a QStandardItemModel instead of a QAbstractItemModel.
This issue is now resolved. It turned out to be a problem in the model: I forgot to tell the root (invalid parent) to accept drops too. This is done in the QAbstractItemModel::flags() implementation.
The incorrect version was:
basically now my model controls text color through Qt::ForegroundRole regardless of the application's CSS.
I feel like it's the wrong place to put theming, but it works for me at the moment.
Well... until we decide to have different themes :-°
The things you have to understand with hierarchical model are:
everything can be done through items
use appendRows (or insertRows) to add one line containing several columns
create a hierarchy on the item that represents the first column with the above appendRows (for instance on "(fffe,e000)" but not on "SQ")
use appendRows (or insertRows) on top level instances only to your model (for instance "(0040,a493)" "CS", "(0040,a504)" "SQ", but not "(0008,0105)" "CS")
To view your hierarchy, create a QTreeView and give it this model.
The thing is, that i need this dots to be separate items, since they are used as clickable buttons. I tried to inherit from QTreeView and override drawRow, but when i do that, i need to override visualRect, indexAt and some other methods too, and that's realy inconvenient. Is there another way to reach my goals with QTreeView , or do i need to inherit from QAbstractItemView, and implement this kind of TreeView myself?
Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.