How to implement a Clickable Widget for QListView? - qt

I want to implement my own Widgets for a QListView. Like this:
If i click on this widget i want to do something.
In time, I only have experience with the QML-Version of the ListView.
Can someone explain how to insert this widget to the a QListView?
Greetings
UPDATE
In my Project i want a GUI like this:
In my first ListView I want to show items, that has a ListView, too. The text of each item can to be update.

There are 2 ways:
Set custom widget for each index: QAbstractItemView::setIndexWidget. Note: there may be problems with interaction with widgets. This way is typically used only for displaying static content.
Create custom QStyledItemDelegate and override editorEvent method. See model-view programming for details.
Update:
I propose you next design:
Create widget with image list + "dynamic content" + labels
Create ScrollArea with vertical layout and add there widgets (1.)
(2.) is prefferable than simple listview, because listview doesn't design for such cases. Listview designed for showing some data, but not to be a container for other complex widgets.
Pros: you will have fully interactable widgets.
Cons: you need to code a bit ;)

Related

Complex content in QTableView

We would like to do a TableView that allows complex content in its cells.
The TableView should be as generic that I can do simple stuff like in picture 1. The left image is a simple example, where I fill a simple TableModel, set it for the TableView and display it.
But what if I want to add more complex content to one cell? Please again look at the first picture. The right part is more complex, for every cell we want to display an image, a description, and more description, so three items in one cell.
I understand, that I can put widgets to the cells of a TableView.
But, if I want to have a proper TableModel in the background, how would I store the data?
On top, the view should automatically resize when I make the widget of the TableView smaller the content should adapt
So if I use TableView and want to resize, I would have to shovel the content from one colum to another.
From what I understand, the columns also define the layout.
Would I be better of if I used a QGridLayout for this purpose?
Do I have to define a completely new model for QGridLayout?
Thanks for any help!
I am a newbie to QT and would appreciate your input a lot!
Qt's proposed solution to having a complex view in each cell of a table view is to use a custom delegate. Take a look at Star Delegate example, it demonstrates exactly this technique.
There are basically two options to proceed with a custom delegate: either you subclass QStyledItemDelegate (or its base class QItemDelegate if you need to draw the items of Qt's datatypes somewhat specially) or subclass QAbstractItemDelegate to have the full control over the delegate's appearance and behaviour.
However, your second requirement of automatic layout rearrangement on widget resizing suggests that your view doesn't really has to follow the underlying table's schema. Qt has a flow layout example which implements a layout with exactly this rearrange-on-resize property and I suppose the simplest approach would be just using this layout along with custom widgets representing the table model's cells. To make it happen you could implement a custom view class listening to the model's signals and creating/deleting widgets and updating the flow layout as necessary. This book, even though a little outdated nowadays as it covers Qt4, contains a chapter (#6) on implementing a custom view which is not a subclass of QAbstractItemView but is just a widget updating itself as its underlying model updates. To me it feels the right approach to your problem.

ItemDelegate vs ProxyModel Subclass

I'm have to create a form where some questions will be taken from the db. Each question will have two radioButtons (Yes / No), a label "Explain..." and a textEdit.
Firstly I created this in a QScrollArea, where for every question in the db (taken with QSqlTableModel) all the necessary widget were created and put into the layouts.
Now I think I would better do it in a QListView, where an item will be all the question = its information (question + 2 radioButtons + label + textEdit + its Layouts). I thought I could easily do it with QAbstractItemDelegate, so I created a subclass for it, but I am having some problems though.
The question are not shown at all, even are its informations. Should I use a subclass of ProxyModel instead? I found a very useful checkableProxyModel! subclass which added a checkbox for every item in a model, and I thought if it was possible to add a checkBox, maybe it is possible to add all this information?
Any idea?
Comment if you need any code.
The Qt Model & View classes only provide the ability to have an additional checkbox, by including Qt::ItemIsUserCheckable in the flags return value of QAbstractItemModel::flags(). The Qt MV classes however don't allow any custom widget like radio buttons to be used as the delegate.
One way to render a widget would be using QStyle::drawComplexControl() in your QAbstractItemModel::paint() reimplementation, but that gets difficult when you have multiple widgets like in your case, and it doesn't handle interaction.
A better way would be to use QAbstractItemView::setIndexWidget(), but see this bug report for a Qt developer talking about the performance implications.

QT QtreeView show image when tree is expanded and collapsed

I have a requirement in the TreeView where I have to show down arrow image when tree is collapsed and up arrow image when tree is expanded and this is applicable for each parent item in the tree.
My UI will have only 1 column and this arrow images i have to show at the end of the row.
I am using QTreeView and I can see expand and collapse signals.But it does have only index arguement.But I need item rectanlge details to show the image at the end of the row.Could you pls suggest is there any way to achieve this?
Thanks,
The simplest way would be to use QTreeView::setIndexWidget (inherited from QAbstractItemView). With this method, you can set your own widget to render the nodes.
If you have more sophisticated requirements, you need to implement a custom delegate. Please have a look at the QAbstractItemDelegate Class Reference and Designing Delegates. By the use of delegates, you have complete rendering control over your items.

Qt: Custom QListView and live controls

My custom QListView has delegates to paint the items. I'd like to add a live control to some of the row items (like a QLineEdit), that'll always be present in the row and will automatically scroll correctly with the list.
Since items are not widgets, I cannot assign a control to be a child of an "item", thus scrolling will leave the control in its fixed spot within the QListView widget.
Is there another way?
Is that even possible?
Normally the edit widget is created (and positioned) by the delegate when an QEvent::EnterEditFocus event occurs then destroyed when a subsequent QEvent::LeaveEditFocus occurs and the data is sent back to the model. The delegate should then repaint with the new model data.
Could you expand on what you mean by a "live" control?
Why would you want to have an edit widget constantly open? I think a better way to do this would be to create a delegate which paints the normal view (i.e. for Qt::DisplayRole) in a way which you want. Assuming you create your subclass view correctly, the delegate should still update when the model changes.
If you really want to do what you're asking though, I suspect you might be able to by:
creating your own item delegate (subclassing QAbstractItemDelegate)
reimplement createEditor() to use a QLineEdit
then use the delegate's updateEditorGeometry()
Have a read of the Delegate Classes section of the Introduction to Model/View Programming though first. The Spin Box Delegate Example and Pixelator Example are worth studying too if you haven't already.

How to use Qt's Model-View programming

I'm trying to display some cards into a QListView but I'm really having trouble understanding how to use Qt's model/view pattern, and I can't find any simple examples.
Basically, I have two classes:
Card - my "model" which contains the name of the card, id, etc.
CardWidget - can load and render a Card object (display the card name and other info)
So how can I use Card and CardWidget to display a list of cards into a ListView? Do I need to change something to my classes, or should QListView be able to display them directly?
If someone could show me the basic steps or point me in the right direction that would be perfect.
See the documentation of QAbstractItemDelegate, which has an example of rendering items in a QTableView.
Its not obvious what you are trying to do here - in a list view, you can render a view of an item which is not the same as having a widget in every cell.
An item delegate can provide a widget as an editor and also how to render a cell's contents.
If you actually want fixed widgets in the view, you could use QListView::openPersistentEditor on all the cells you want a fixed widget for. The item delegate should outline how to create an editor for the cell in question.

Resources