PDA

View Full Version : QTreeView details: what are viewItems?



neuronet
1st January 2015, 02:16
I am working on understanding trees, working through the simpletreemodel example that comes with Qt. I am working in PySide, not Qt, and while I don't know much c++ I often find it helpful to look at the Qt source code to help me understand what is happening.

I understand indexes a bit (because of a thread here (http://www.qtcentre.org/threads/61213-Source-code-for-createIndex%28%29)), and now am trying to understand QTreeView, in particular how it paints the initial tree, determines what to draw, when/where it calls model.rowCount() and other methods from my QAbstractItemModel subclass.

I've been looking over qtreeview.cpp (https://qt.gitorious.org/qt/qt/source/5fe6a7457033b183d8cc3861fe8593338ad3385b:src/gui/itemviews/qtreeview.cpp) and am confused. My first confusion is about what the 'd' class is. I think it is an instance of QTreeView, because starting on line 196 we have:

QTreeView::QTreeView(QTreeViewPrivate &dd, QWidget *parent)
: QAbstractItemView(dd, parent)
{
Q_D(QTreeView);
d->initialize();
}
But there are lots of methods/attributes of d that I cannot find defined anywhere. For instance viewItems seems pretty key, and has many methods (e.g., resize(), clear()) that I'd like to study. Unfortunately I am not sure where viewItems is defined initially, what it means. I have never seen it documented, or used it explicitly in my custom views. In addition to qtreeview.cpp, I searched for it in qtreeview.h (https://qt.gitorious.org/qt/qt/source/57756e72adf2081137b97f0e689dd16c770d10b1:src/gui/itemviews/qtreeview.h), qabstractitemview.cpp (https://qt.gitorious.org/qt/qt/source/9d9b7f53750dce2da88d7d11d312b4b36250b5c5:src/gui/itemviews/qabstractitemview.cpp), and qabstractitemview.h (https://qt.gitorious.org/qt/qt/source/57756e72adf2081137b97f0e689dd16c770d10b1:src/gui/itemviews/qabstractitemview.h).

So I seem to be having a problem similar to when I was tracking down the definition of createIndex. Namely, figuring out where to find the relevant source code.

More generally, anyone please let us know if you have seen a good nuts 'n' bolts explanation of how QTreeView works. I have found high-level descriptions of what is going on (e.g., the view uses indexes to determine what to paint to the screen), but I really want to know more under the hood. I have started putting print commands in the model for all the methods (e.g., rowCount), but this has made me even more confused: for instance, sometimes it is calling rowCount with input from a parent index from a row that is way below my selection. :confused:

Thanks for reading.

anda_skoa
1st January 2015, 14:54
The d-pointer idiom is used to keep the public API of QTreeView binary stable while still having the option of adding/removing/renaming functions necessary for the view's procesing.

The d-pointer points to a private class that holds the actual implementation of the view, often also referred to as PIMPL idiom (pointer to implementation).

The Q_D() and Q_Q() macros enable const correct access to the private and public class respectively.

The class you are looking for ist QTreeViewPrivate

Cheers,
_

neuronet
1st January 2015, 17:39
The d-pointer idiom is used to keep the public API of QTreeView binary stable while still having the option of adding/removing/renaming functions necessary for the view's procesing.

The d-pointer points to a private class that holds the actual implementation of the view, often also referred to as PIMPL idiom (pointer to implementation).

The Q_D() and Q_Q() macros enable const correct access to the private and public class respectively.

The class you are looking for ist QTreeViewPrivate

Cheers,
_

Thanks I will ruck about see what I figure out and post here.

ChrisW67
1st January 2015, 20:05
Within the Qt source the private implementation is usually in a file named blah_p.h for a class blah with its public API in blah.h. The private header is #included into the implementation file blah.cpp but not inthe public header or user programs.

I would not worry too much about the internals of the views and models if all you want to do is use them.

neuronet
1st January 2015, 22:14
Within the Qt source the private implementation is usually in a file named blah_p.h for a class blah with its public API in blah.h. The private header is #included into the implementation file blah.cpp but not inthe public header or user programs.

I would not worry too much about the internals of the views and models if all you want to do is use them.

Thanks a lot for the specifics, that is helpful, though I am frankly still a bit lost.

tl;dr : Good point: my goal is just to use this software, not become a developer. If it really is important I learn the internals, I will need to learn Qt for real (c++).

The problem is, as I try to explain to other PySide users what is going on underneath, I often have no idea. For instance "Why the redundancy between model.data() and index.data(): why not always use one or the other?" It is frustrating to not be able to go in and figure such things out easily on my own. c++ code is a labyrinthine mystery to me for the most part. For some things, going to the source is really helpful. With QTreeView, it has been mostly frustrating.

anda_skoa
1st January 2015, 22:22
QModelIndex::data() is for convenience, in case you want to retrieve data pointed to by a QModelIndex.

But the data retrieval function has to be implemented somewhere and since one cannot "inject" something into QModelIndex, the next possible place is the model.

So QModelIndex::data() can then always be just a simple indirection


QVariant QModelIndex::data(int role) const
{
model()->data(*this, role),
}


Cheers,
_

neuronet
2nd January 2015, 03:35
I found a great Doxygen resource (http://cep.xray.aps.anl.gov/software/qt4-x11-4.2.2-browser/classes.html) for navigating Qt (unfortunately only up to 4.2 I couldn't find any doxygenated 4.8: if anyone has a link let me know...).

Using it made navigating the c++ code much easier, and the code seems largely the same as in 4.8, so I've been using the doxygen pages (for 4.2) to find stuff in 4.8. For instance, the documentation for qtreeview_p.h (http://cep.xray.aps.anl.gov/software/qt4-x11-4.2.2-browser/d3/d15/class_q_tree_view_private.html) has the following useful bit:

QVector<QTreeViewItem> QTreeViewPrivate::viewItems [mutable]
Definition at line 134 of file qtreeview_p.h.

Cool, we have a QVector of QTreeViewItems, and this is the mysterious viewItems that I was asking about! Many of the viewItems methods were actually just QVector methods, and part of my confusion is that QVector is not part of PySide.

At any rate, in 4.8, on line 178 (https://qt.gitorious.org/qt/qt/source/85e95859047d2c198e495cd4cb6a4352df76e6d4:src/gui/itemviews/qtreeview_p.h#L178)), we see the relevant line:
mutable QVector<QTreeViewItem> viewItems;So we have a vector of QTreeViewItem types, and QTreeViewItem has its own page here (http://cep.xray.aps.anl.gov/software/qt4-x11-4.2.2-browser/d1/d3d/struct_q_tree_view_item.html). But more importantly, qtreeviewitem is the first structure (https://qt.gitorious.org/qt/qt/source/85e95859047d2c198e495cd4cb6a4352df76e6d4:src/gui/itemviews/qtreeview_p.h#L64-178) defined in qtreeview_p.h! In terms of clues about when it is being populated, check line 2495 of qtreeview.cpp (https://qt.gitorious.org/qt/qt/source/5fe6a7457033b183d8cc3861fe8593338ad3385b:src/gui/itemviews/qtreeview.cpp#L2495) (d->viewItems.insert(insertPos, delta, insertedItems.at(0))). Where 'insert' seems to be a built-in method for QVectors.

This seems like a very promising line of attack for other Python users (perhaps future me) to insinuate themselves into this often baffling code.