Results 1 to 19 of 19

Thread: QSql*Model + QTreeView : make a tree

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Sep 2008
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSql*Model + QTreeView : make a tree

    Yesterday I was finally able to get my tree model working from my SQL query results. I have to say took me a while to see where I needed to be going. In the end I dump my results into a QAbstractTableModel, then build up a tree item model that gets it's data from this table. Then I use a QSortFilterProxyModel to display the tree. My code is a little ugly right now (I really need to subclass some of this), but I can use either a table model or a tree model to display the same search data.

    The QSortFilterProxyModel is a bit of overkill for this, but the nice thing is that it has already subclassed and connected everything to make sure that the proxy model updates whenever the table model does.

    If any one wants to see what I ended up doing let me know and I can post the code.

    -- amicitas

  2. #2
    Join Date
    Sep 2008
    Posts
    13
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QSql*Model + QTreeView : make a tree

    Janus wanted to take a look-see at my code, so I figured I would post it for everyone. It is not particularly polished code, but it does the job.

    For this application I am doing a SQL query that returns a table of songs. Each record has a number of columns including artist, album & track. I want to turn this table into a tree. To do this I use a TableModel and a ProxyModel.

    Here is a basic description of what happens:
    1. An SQL query is performed.
    2. The results from the query, along with the column names is added to the HystrixSearchModel. This data is added as a table.
    3. A set of tree items is generated for the data.
    4. reset() is called to let both the HystrixSeachModel and the HystrixProxyModel know that the data has changed.
    5. The proxy model displays the data from the tree items.


    For most of this I followed along with the "Simple Tree Model Example" in the Qt documentation. I did not document in the code the stuff that is documented there.

    Since the file is too big to put in this post here is a link to it on sourceforge.
    (Note that this is written in Python using PyQt4, you C++ people will have to translate.)
    (as a hint though, python passes all mutable objects as pointers, so only references to the data are stored in the tree items.

    hystrix_model.py


    To use this model in a view I use:
    Qt Code:
    1. #
    2. # Create the View (HystrixTreeView is subclassed from QTreeView
    3. ui_search_view = HystrixTreeView(self)
    4.  
    5. # Create the data model
    6. search_model = hystrix_model.HystrixSearchModel()
    7.  
    8. # Create the proxy model
    9. proxy_model = hystrix_model.HystrixProxyModel()
    10.  
    11. # Connect the model
    12. proxy_model.setSourceModel(search_model)
    13.  
    14. ui_search_view.setModel(proxy_model)
    To copy to clipboard, switch view to plain text mode 


    In the code the tree items are built by: HystrixSearchModel.makeTreeItems

    I also have a routine in there called: HystrixSearchModel.makeIndexedTreeMap

    makeIndexedTreeMap is not actually used, but it is easier to see how I am building the tree in that routine. If you are having trouble figuring out what I am doing in makeTreeItems then look at makeIndexedTreeMap first.


    For my proxy model I subclass QSortFilterProxyModel. I don't actually use any of the filtering or sorting abilities, but that class already has all necessary parts of QAbstractProxyModel reimplemented and the signals, slots and events are all connected up. To use the QAbstractProxyModel directly requires a whole lot of work.

    If anyone has questions let me know and I will be happy to answer them.

    Good luck.

    -- amicitas
    (that code snippit is part of Hystrix Audio Hystrix Audio)

  3. #3
    Join Date
    Mar 2008
    Posts
    141
    Thanks
    10
    Thanked 9 Times in 9 Posts

    Default Re: QSql*Model + QTreeView : make a tree

    Hi,

    thx to amicitas and other posts in this thread I was able to build a tree from sql. But I am not using a model: On startup i execute a query for the parent items (children of the rootitem). My problem was, that I want to load only the data form the database that are visible at the beginning otherwise the whole thing is too slow. When the user clicks a parent (all of them have children) I execute another query to load the childitems. This is quite fast and works. My problem is, that i am not able to connect to the expanded() signal of the treeView. Right now I am hiding the decoration (setRootIsDecorated(false)) and use clicks on items within the view to expand or collapse. The expanding is done within the model ...
    Qt Code:
    1. connect(ui.treeView, SIGNAL(clicked(QModelIndex)), model, SLOT(expand(QModelIndex)));
    2.  
    3. connect(ui.treeView, SIGNAL(expanded(QModelIndex)), model, SLOT(expand(QModelIndex))); //<-- no way. infinite loop
    4.  
    5. void TreeModel::expand(const QModelIndex &index)
    6. {
    7. QModelIndex idx = proxy->mapToSource(index);
    8.  
    9. QModelIndex sourceIndex = idx.sibling(idx.row(), 0);
    10. QModelIndex proxyIndex = index.sibling(index.row(), 0);
    11.  
    12. if (!hasChildren(sourceIndex))
    13. return;
    14.  
    15. TreeItem *item = getItem(sourceIndex);
    16.  
    17. if (item->childCount() > 0) {
    18.  
    19. if (view->isExpanded(proxyIndex)) {
    20. view->collapse(proxyIndex);
    21. return;
    22. }
    23.  
    24. view->expand(proxyIndex);
    25.  
    26. }
    27.  
    28. else {
    29.  
    30.  
    31. .. execute query
    32.  
    33. setupModelData(q, item);
    34. view->expand(proxyIndex);
    35.  
    36. }
    37.  
    38. }
    To copy to clipboard, switch view to plain text mode 

    This is not a very nice solution. I'd rather prefer to use the default rootdecoration. But i can not find a way to get the expanded signal and load the data: Nothing is dispayed because the signal is emitted after the view is updated (At that point there is no data). If I call the expand slot again after the query I end up in an infinite loop ... I took a look at the Qt source code, but all parts that are required to cache the expansion (the click on the decoration [+] ) before the model is checked for children are part of QTreeViewPrivate. Sorry for the long explanation, but maybe someone has an idea :-)

Similar Threads

  1. QTreeView with QStandardItemModel
    By steg90 in forum Newbie
    Replies: 3
    Last Post: 16th May 2007, 09:28
  2. Replies: 3
    Last Post: 19th April 2007, 11:42
  3. Window OS make distclean && qmake && make one line
    By patrik08 in forum General Programming
    Replies: 4
    Last Post: 22nd March 2007, 10:43
  4. Compiling with Qmake/Make
    By VireX in forum Newbie
    Replies: 25
    Last Post: 22nd February 2007, 05:57
  5. Optimizing filterAcceptsRow() to filter a tree
    By vfernandez in forum Qt Programming
    Replies: 1
    Last Post: 4th January 2007, 12:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.