How to deal with QPushButton in a item of a QListview
-
Hello, everyone.
I want to add some buttons(QPushButton) and strings on each item of a QListview throught QItemdelegate, Now I could display the strings on a QListview. so my next step is to add the button.
My questions are:
(1)how to add the buttons, through the paint() function of QItemDelegate?
(2)how to deal with the signal (e.g:clicked()) that QPushButton emit ?
Thanks for all suggestions.
best regards
Hisong. -
[quote author="hisong1988" date="1293440313"]Hello, everyone.
I want to add some buttons(QPushButton) and strings on each item of a QListview throught QItemdelegate, Now I could display the strings on a QListview. so my next step is to add the button.[/quote]
Are you making a list of buttons or what? Perhaps a QTreeView with a undecorated root is a better idea...
[quote]
My questions are:(1)how to add the buttons, through the paint() function of QItemDelegate?
[/quote]If the button contents do somehow depend on the item's data, yes. Subclass QItemDelegate or QStyledItemDelegate and paint the pushbutton yourself. If the button does not depend on the underlying data, use setIndexWidget.
[quote]
(2)how to deal with the signal (e.g:clicked()) that QPushButton emit ?
[/quote]If you're using setIndexWidget it's straigtforward. If you're using a delegate, you won't have a "real" QPushButton, you'd just be painting it, therefore all signals must be handled by you (subclassing the view and emitting the signal or so).
-
Using widgets in item views is very tricky. Drawing a button using QItemDelegate is one thing, but making it actually work as a button is quite another. Qt itself supplies a method to use widgets for items, see QAbstractItemView::setIndexWidget for that. Note the warning in the documentation.
Another approach is available through a piece of code from the KDE project (note the licence) called KWidgetItemDelegate, formally known as Goya. It works fine, but it is not entirely trivial and it can cause a bit of performance penalty for large models.
As a last suggestion, you might considder, depending on your needs, using a QML view (QDeclarativeViewO and create your list in QML. That will make it easy to draw your own items (including a button) and respond to signals, but it will be harder to really integrate into your application, especially if you need to support multiple platforms.
-
Thank peppe and Andre.
[quote author="peppe" date="1293442697"]
If you’re using setIndexWidget it’s straigtforward. If you’re using a delegate, you won’t have a “real” QPushButton, you’d just be painting it, therefore all signals must be handled by you (subclassing the view and emitting the signal or so).
[/quote]
My buttons is not depend on the item. But if I have already use the QItemDelegate, could I use the setIndexWidget? Now I now how to paint a pushbutton,as you said ,it is not real.
I also custom a "model", how to bind signals to buttons? -
[quote author="Andre" date="1293442861"]Using widgets in item views is very tricky. Drawing a button using QItemDelegate is one thing, but making it actually work as a button is quite another. Qt itself supplies a method to use widgets for items, see QAbstractItemView::setIndexWidget for that. Note the warning in the documentation.
[/quote]At first I had noted that the setIndexWidget() method. But the method had a note:
If you want to display custom dynamic content or implement a custom editor widget, subclass QItemDelegate instead.
I think that my item is not a static item(with buttons). So I decide to use the QItemDelegate.
-
I have no experience with using setIndexWidget in combination with custom QItemDelegates. No idea if that will work. Just try and see?
On how to handle the signals: since you have to create the widgets yourself, you also have control over creating the connections. I think I'd just create a QSignalMapper instance, and hook up the buttons to the mapper linked with the row number. You can then use a single slot connected to the mapped(int) signal of QSignalMapper.
-
I think you should avoid using QListView on mobile screens because QListView is not made for mobile screens, it's rather a Desktop widget.
What you can do is use QScrollArea and use custom made widgets inside it, use a QVBoxLayout to place them vertically.
-
For how to use the QPushButton you can have look here : "Class QPushButton":http://doc.qt.nokia.com/latest/qpushbutton.html
About how the QPushButton emit signal : "Use QObject":http://wiki.forum.nokia.com/index.php/How_to_use_QPushButton_in_Qt
-
[quote author="Milot Shala" date="1293453592"]I think you should avoid using QListView on mobile screens because QListView is not made for mobile screens, it's rather a Desktop widget.
What you can do is use QScrollArea and use custom made widgets inside it, use a QVBoxLayout to place them vertically.[/quote]
Oh,no,I have implement the itemDelegates in my listview, but I could only draw the string and the buttons on the items, how to bind the signals to the button is not achieved. It is a little difficult for me.
Milot Shala, would you give me an example or a code snippet about how to use use QScrollArea and use custom made widgets inside it?
-
[quote author="qtrahul" date="1293455183"]For how to use the QPushButton you can have look here : "Class QPushButton":http://doc.qt.nokia.com/latest/qpushbutton.html
About how the QPushButton emit signal : "Use QObject":http://wiki.forum.nokia.com/index.php/How_to_use_QPushButton_in_Qt[/quote]
Thanks, I know how to emit a signal with a custom widget and how to use the QPushButton.
But in the listview, I don't know how to "create" buttons and use them. -
You have to add the buttons yourself. It's usually done in the class that contains the list view. As you use a list view you will also have a model. Connect to the columnsInserted and rowsInserted signals to catch changes in the model and add the buttons for the new data in the view. Also signals columnsAboutToBeRemoved and rowsAboutToBeRemoved should be connected in order to remove the index widgets before the model deletes the rows/columns.
-
[quote author="hisong1988" date="1293455342"]
[quote author="Milot Shala" date="1293453592"]I think you should avoid using QListView on mobile screens because QListView is not made for mobile screens, it's rather a Desktop widget.What you can do is use QScrollArea and use custom made widgets inside it, use a QVBoxLayout to place them vertically.[/quote]
Oh,no,I have implement the itemDelegates in my listview, but I could only draw the string and the buttons on the items, how to bind the signals to the button is not achieved. It is a little difficult for me.
Milot Shala, would you give me an example or a code snippet about how to use use QScrollArea and use custom made widgets inside it?[/quote]
Think about event filters and installing them on the viewport. A colleague of mine implemented kinetic scrolling feature using the technique I just mentioned, maybe his idea will help you.
"Here's the idea and the implementation":http://wiki.forum.nokia.com/index.php/Qt_Kinetic_scrolling_-_from_idea_to_implementation
-
[quote author="Milot Shala" date="1293466891"]
Think about event filters and installing them on the viewport. A colleague of mine implemented kinetic scrolling feature using the technique I just mentioned, maybe his idea will help you.
"Here's the idea and the implementation":http://wiki.forum.nokia.com/index.php/Qt_Kinetic_scrolling_-_from_idea_to_implementation[/quote]
I think I should test the QItemDelegate first, but how to use the filters? I noted that there are two methods of QItemDelegate:
@
virtual bool editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index )
virtual bool eventFilter ( QObject * editor, QEvent * event )
@
Does it mean that I should implement both of them?
and how to "catch" the event that the buttons I painted? -
p.s. My buttons only deal with the parameter QModelIndex & index, and each button of the item would be the same appearance and location. But the strings was depended by the model
-
[quote author="hisong1988" date="1293504838"][quote author="Milot Shala" date="1293466891"]
Think about event filters and installing them on the viewport. A colleague of mine implemented kinetic scrolling feature using the technique I just mentioned, maybe his idea will help you.
"Here's the idea and the implementation":http://wiki.forum.nokia.com/index.php/Qt_Kinetic_scrolling_-_from_idea_to_implementation[/quote]
I think I should test the QItemDelegate first, but how to use the filters? I noted that there are two methods of QItemDelegate:
@
virtual bool editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index )
virtual bool eventFilter ( QObject * editor, QEvent * event )
@
Does it mean that I should implement both of them?
and how to "catch" the event that the buttons I painted?[/quote]
No you should implement only the eventFilter then use installEventFilter(QObject*) on a widget. Please read "this":http://doc.trolltech.com/4.7/eventsandfilters.html part of the docs.
-
If you go for the item delegates, I'd strongly recommend sublcassing "QStyledItemDelegate":http://doc.qt.nokia.com/stable/qstyleditemdelegate.html as it is the default used by Qt itself.