Results 1 to 14 of 14

Thread: ListView and CurrentChanged

  1. #1
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question ListView and CurrentChanged

    I'm using a listview with a custom made model where the items in the listview are delegates.

    I can't seem to get clicking on the list view to trigger selection changed. It looks like its because the delegate uses a label to render the information.

    Here are some code bits:

    This is the paint function in the delegate. The viewPtr is defined elsewhere and is a pointer to the view.

    Qt Code:
    1. void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
    2. const QModelIndex &index) const
    3. {
    4. painter->save();
    5.  
    6. std::cout << "Row: " << index.row() << std::endl;
    7.  
    8. if(viewPtr->indexWidget(index) == NULL)
    9. {
    10. QLabel *label = new QLabel();
    11. Data *data = qVariantValue<Data*>(index.data(Qt::DisplayRole));
    12. QString displayValue = data->displayValue();
    13. label->setAutoFillBackground(true);
    14. label->setWordWrap(true);
    15. label->setText(displayValue);
    16.  
    17.  
    18. if(option.state & QStyle::State_Selected)
    19. {
    20. //painter->fillRect(option.rect, option.palette.highlight());
    21. label->setPalette(option.palette);
    22. label->setBackgroundRole(QPalette::Highlight);
    23. viewPtr->setIndexWidget(index, label);
    24. QItemDelegate::paint(painter, option, index);
    25. }
    26. else
    27. {
    28. if(index.row() & 1)
    29. {
    30. //painter->fillRect(option.rect, QBrush(QColor("#c0c0c0")));
    31. p.setBrush(QPalette::Background, QBrush(QColor("#c0c0c0")));
    32. label->setPalette(p);
    33. label->setBackgroundRole(QPalette::Background);
    34. viewPtr->setIndexWidget(index, label);
    35. }
    36. else
    37. {
    38. //painter->fillRect(option.rect, QBrush(QColor("#dddddd")));
    39. p.setBrush(QPalette::Background, QBrush(QColor("#dddddd")));
    40. label->setPalette(p);
    41. label->setBackgroundRole(QPalette::Background);
    42. viewPtr->setIndexWidget(index, label);
    43. }
    44. QItemDelegate::paint(painter, option, index);
    45. }
    46. }
    47. painter->restore();
    48. }
    To copy to clipboard, switch view to plain text mode 

    I've tried the following to no avail:

    Qt Code:
    1. MyDelegate delegate;
    2. delegate.setViewPointer(window->listView);
    3. window->listView->setItemDelegate(&delegate);
    4. QObject::connect(window->listView, SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
    5. &delegate, SLOT(selected(const QModelIndex &current, const QModelIndex &)));
    To copy to clipboard, switch view to plain text mode 

    The delegate class has a selected slot that I've defined.

    Where am I going wrong? The above code works if I'm not using a label...

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    You create your delegate on the stack, so it goes out of scope immediately. As for the label, try installing an event filter to catch the mouse click.
    Last edited by jacek; 22nd March 2007 at 22:13.

  3. #3
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    The creation of my delegate is in the main function. That may not be the best place to declare the object, but that's how I'm doing it right now.

    I will take a look event filters. Thanks Jacek.

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Quote Originally Posted by kroenecker View Post
    The creation of my delegate is in the main function. That may not be the best place to declare the object, but that's how I'm doing it right now.
    If it's in main(), then it doesn't matter how you create it.

  5. #5
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    This makes me wonder:

    If you use a delegate in a model that displays a custom widget, where is the click event handled? By the delegate? By the widget? By the view?

    This is rather ambiguous to me.

    If the model handles it then I would think that simple connecting the signals as I did would solve the problem. However, nothing seems to happen.

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Quote Originally Posted by kroenecker View Post
    If you use a delegate in a model that displays a custom widget, where is the click event handled? By the delegate? By the widget? By the view?
    If you show a widget in a cell, then most likely you want it to behave normally (i.e. just as if it was shown in some other place) and since you can't tell what events such arbitrary widget needs to process, the simpliest solution would be to make it handle all possible events.

  7. #7
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Well I created a custom label that derives from QLabel and that successfully intercepts the mouse click event, but I have no idea how to tell the view that it now needs to select that particular item.

  8. #8
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    I thought about changing the labels background color, but then multiple backgrounds would be changed over time. I only want one item to be selected at a time.

    Trying to figure this stuff out is extremely time consuming.

  9. #9
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Quote Originally Posted by kroenecker View Post
    but I have no idea how to tell the view that it now needs to select that particular item.
    Maybe through QItemSelectionModel?

  10. #10
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Well I've been passing pointers around like crazy....

    The labels have pointers to the modelindexes that they display. They also have pointers to the view. When clicking on the labels, the mousePressEvent is called. In the event I can use the view's pointer to call the selection model and set the current label's index as the selected item. This, however, changes nothing in the delegates paint event. I can call the selection model in the paint event and it doesn't see the index as being selected.

    How weird and utterly annoying is that?

    Why am I always butchering this Model/View stuff? Oh yeah, it's because there isn't any good documentation for it :{

  11. #11
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    By the way I do appreciate your help. I'm just trying to vent a little. As much as I love open source stuff, I'm always hitting roadblocks like this.... :P Must be me

  12. #12
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Quote Originally Posted by kroenecker View Post
    The labels have pointers to the modelindexes that they display.
    Well... I should have asked it in the first place, but what do you need those labels for?

  13. #13
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    Jacek,

    Well I wanted to be able to populate a listview with information that is rendered as rich-text.

    I guess I just don't understand how all these different parts intersect.

    Like I said above, if I don't use labels, I can simply populate each item in the view with text using painter->setText(*params*) and, in that case, selecting works just fine. I just don't understand why the label event handler shows that an item is selected (it's in the event handler that I use the selection model to select items in the view), but in the
    Qt Code:
    1. void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    To copy to clipboard, switch view to plain text mode 

    call none of the items show up as being selected. In both instances I'm using what I would assume is the same pointer to the same selectionModel. I guess that somewhere along the line the selectionModel's values are being changed. Oh well, I just don't get it.

    If I can get the text to wrap in the paint call, then I guess I don't need to use a label.

  14. #14
    Join Date
    Jan 2006
    Posts
    75
    Thanks
    8
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: ListView and CurrentChanged

    To answer my own question it looks like I can set that sort of thing with the text displayed by paint... Silly me

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.