Results 1 to 10 of 10

Thread: tree view displaying widgets as items

  1. #1
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default tree view displaying widgets as items

    Hi

    I need to make a tree of widgets.

    I tried using a QTreeView and a subclassed QAbstractItemModel, but I coulnd't figure out how the tree view woould know how to draw my widgets, since the model only provides it with QVariant data.

    Then I read this post: inserting custom Widget to listview, and I ust admit it made me really confused.

    Could you please point me to an example or give me some pointers how to achieve my goal.

    I must add, that I will need to dsplay all kinds of widgets in the tree - not only labels and buttons.

    Thanks,
    Paksas

  2. #2
    Join Date
    Jan 2006
    Location
    Belgium
    Posts
    1,938
    Thanked 268 Times in 268 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Wiki edits
    20

    Default Re: tree view displaying widgets as items

    Here's another example:
    http://doc.qt.nokia.com/4.6/itemviews-stardelegate.html

    Can you describe what makes you confused or what you do not understand?

  3. #3
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    Quote Originally Posted by tbscope View Post
    Here's another example:
    http://doc.qt.nokia.com/4.6/itemviews-stardelegate.html

    Can you describe what makes you confused or what you do not understand?
    The example you quoted also shows a non-widget class being edited by an external editor (derrived from a qwidget). The delegate operating on it accepts a QVariant data - to which a StarRating class instance can be cast.

    What I want is to embed any QWidget directly, and with this approach it raises a few questions:
    - where can I get an editor from for let's say a QLabel or a QTextBox?
    - how can I cast the widgets to a QVariant?

    Here's the delegate class I wrote - but it doesn't work because of the problems I mentioned.


    #include <QStyledItemDelegate.h>
    #include <QPainter.h>
    #include <QWidget.h>

    class WidgetItemDelegate : public QStyledItemDelegate
    {
    public:
    /**
    * Constructor.
    *
    * @param parent parent widget
    */
    WidgetItemDelegate( QWidget* parent = NULL );

    // -------------------------------------------------------------------------
    // QStyledItemDelegate
    // -------------------------------------------------------------------------
    void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
    QSize sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const;
    QWidget* createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const;
    void setEditorData( QWidget *editor, const QModelIndex &index ) const;
    void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const;

    private slots:
    void commitAndCloseEditor();
    };

    ///////////////////////////////////////////////////////////////////////////////

    WidgetItemDelegate::WidgetItemDelegate( QWidget* parent )
    {
    }

    ///////////////////////////////////////////////////////////////////////////////

    void WidgetItemDelegate::paint( QPainter *painter,
    const QStyleOptionViewItem &option,
    const QModelIndex &index ) const
    {
    if ( qVariantCanConvert< QWidget* >( index.data() ) )
    {
    QWidget* widget = qVariantValue< QWidget* >( index.data() );

    if ( option.state & QStyle::State_Selected )
    {
    painter->fillRect( option.rect, option.palette.highlight() );
    }

    widget->render( painter );
    }
    else
    {
    QStyledItemDelegate::paint( painter, option, index );
    }
    }

    ///////////////////////////////////////////////////////////////////////////////

    QSize WidgetItemDelegate::sizeHint( const QStyleOptionViewItem &option,
    const QModelIndex &index ) const
    {
    if ( qVariantCanConvert< QWidget* >( index.data() ) )
    {
    QWidget* widget = qVariantValue< QWidget* >( index.data() );
    return widget->sizeHint();
    }
    else
    {
    return QStyledItemDelegate::sizeHint(option, index);
    }
    }

    ///////////////////////////////////////////////////////////////////////////////

    QWidget* WidgetItemDelegate::createEditor( QWidget *parent,
    const QStyleOptionViewItem &option,
    const QModelIndex &index ) const
    {
    return QStyledItemDelegate::createEditor( parent, option, index );
    }

    ///////////////////////////////////////////////////////////////////////////////

    void WidgetItemDelegate::setEditorData( QWidget *editor,
    const QModelIndex &index ) const
    {
    QStyledItemDelegate::setEditorData(editor, index);
    }

    ///////////////////////////////////////////////////////////////////////////////

    void WidgetItemDelegate::setModelData( QWidget *editor,
    QAbstractItemModel *model,
    const QModelIndex &index ) const
    {
    QStyledItemDelegate::setModelData( editor, model, index );
    }

    ///////////////////////////////////////////////////////////////////////////////

    void WidgetItemDelegate::commitAndCloseEditor()
    {
    QWidget* widget = qobject_cast< QWidget* >( sender( ));

    emit commitData(widget);
    emit closeEditor(widget);
    }

    ///////////////////////////////////////////////////////////////////////////////

    Thanks for your help
    Paksas

  4. #4
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    I resolved the problem with embedding widgets in the delegates, but another one arose: I can't draw them correctly. I'm trying to embed them in a QTreeWidget, but they are displayed in wrong places, and the collapsed items are still drawn even thought they shouldn't be.

    Here's my delegate's paint method:

    ///////////////////////////////////////////////////////////////////////////////

    void WidgetItemDelegate::paint( QPainter *painter,
    const QStyleOptionViewItem &option,
    const QModelIndex &index ) const
    {
    if ( qVariantCanConvert< QObject* >( index.data() ) )
    {
    QWidget* widget = dynamic_cast< QWidget* >( qVariantValue< QObject* >( index.data() ) );

    if ( option.state & QStyle::State_Selected )
    {
    painter->fillRect( option.rect, option.palette.highlight() );
    }

    widget->move( QPoint( option.rect.left(), option.rect.top() ) );
    widget->render( painter );
    }
    else
    {
    QStyledItemDelegate::paint( painter, option, index );
    }
    }

    And here are the results:
    widgetsTree..png

    when I use the following items setup:
    m_editorsTree = new QTreeWidget( mainWindow );
    m_editorsTree->setItemDelegate( new WidgetItemDelegate() );

    // setup TEST data
    {
    QTreeWidgetItem* item1 = new QTreeWidgetItem( m_editorsTree );
    QObject* label1 = new QLabel( "label 1", m_editorsTree );
    item1->setData( 0, Qt::DisplayRole, qVariantFromValue( label1 ) );

    QTreeWidgetItem* item2 = new QTreeWidgetItem( item1 );
    QObject* label2 = new QLabel( "label 2", m_editorsTree );
    item2->setData( 0, Qt::DisplayRole, qVariantFromValue( label2 ) );

    m_editorsTree->addTopLevelItem( item1 );
    }

    If I don't set thye parent of the labels, they don't get drawn at all, which brought me to conclussion that the parent's possition is taken into account by the QWidget::render method. However - I can't set the parent to a QTreeWidgetItem instance, since it's not a QWidget...

    Can someone please help?

    Thanks,
    Paksas

  5. #5
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: tree view displaying widgets as items

    Better way is to render widget to a QPixmap and then draw this pixmap. Other thing is that you can set Qt::WA_DontShowOnScreen attribute so the widgets are not drawn at all - you have to draw them manually.

    But the thing is: what type of widgets you want to show in tree view? Because QWidget::render() just renders actual state, so it gives you just an image of real widget - rendered button is not a real button, but just a picture so you can't click this button.

    If you want to labels the your whole idea is wrong as you dont need widgets. If you want to show tree of buttons or other simple widgets, then use QStyle or QStylePainter to draw "fake" widgets not using real widgets. Keeping tons of real widgets in memory is rather bad and really slow solution - I checked this: three views with something around 20 widgets on each view gives 80% CPU usage on both cores (don't know why both?) on windows vista/7 while rendering widgets constantly to have such features like vista's progressbar blinking and buttons highlighting.

    Even having QScrollArea with QVBoxLayout with hundred of simple widgets (button + blinking vista progressbar) makes your qscrollarea consume a lot of CPU and works slowly - users would not be happy while using such application.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  6. #6
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    Quote Originally Posted by faldżip View Post
    But the thing is: what type of widgets you want to show in tree view? Because QWidget::render() just renders actual state, so it gives you just an image of real widget - rendered button is not a real button, but just a picture so you can't click this button.
    That's the thing - I want to put any widget I want in there - be it a button, a label, or a whole tree or a table. And ideally - I'd like it to exhibit its regular behavior - without me needing to click it before I can use it ...

    Is there a way to get that?

    I've no problem with having many widgets around - at least for now Let's just say that performance is not an issue.

  7. #7
    Join Date
    Jan 2013
    Posts
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    Hi, Did you find the solution for this?
    I have similar requirement where i have to place a combobox or text edit whenever i click that particular grid in Treeview.Please suggest how this can be done?
    I Thought of using delegate but I found that i have to apply that delegate for full view/row/column but i need to apply it only for particular grid.How to do that?

    Thanks in Advance...

  8. #8
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    Yes - I used QGraphicsProxyWidget. Works really well and allows you to embed any QWidget you like.

    Cheers,
    Paksas

  9. #9
    Join Date
    Jan 2013
    Posts
    2
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    If you dont mind, can you post sample code please.It will be really helpful for me.

    Thanks in Advance...

  10. #10
    Join Date
    May 2010
    Posts
    8
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: tree view displaying widgets as items

    There's not much to see there - you just instantiate a QGraphicsProxyWidget in your QGraphicsItem and that's it.
    Oh - and I use it only for the widgets rendered in a QGraphicsScene. I actually left that custom tree thing, 'cause I didn't find anything suitable.

Similar Threads

  1. Replies: 8
    Last Post: 6th May 2010, 11:17
  2. Tree View
    By bismitapadhy in forum Qt Programming
    Replies: 1
    Last Post: 8th June 2009, 06:31
  3. C++ Tree View operation
    By zeeb100 in forum Qt Programming
    Replies: 9
    Last Post: 18th February 2009, 17:09
  4. problem with tree view
    By boss_bhat in forum Newbie
    Replies: 4
    Last Post: 4th June 2006, 21:03
  5. tree view!!
    By Seema Rao in forum Qt Programming
    Replies: 4
    Last Post: 9th May 2006, 14:09

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.