ItemDelegate vs ProxyModel Subclass - qt

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.

Related

What is the best way to implement this using Qt

I'm totally new to Qt, so I'd be glad to have a wide answer.
Here I drew up some model:
We have a kind of table that contains:
an integer value with a spinbox.
a cell with three(not specifically) grouped radio buttons
Editbox
A button that interacts with this particular editbox.
Also we have 2 buttons to add and remove items from the table.
I did some google search and found out that it can be done via QTableView.
Is there any way to put such complex structures into a cell? Must it be a separate class inherited from QTableView?
If you're going to have up to a hundred or maybe a few hundreds of elements in the table, then use QTableWidget.
If you're going to have too many elements (about thousands), then go for QTableView, and learn model-view programming.
The reason why I recommend QTableWidget is because you're a beginner. All you have to do there is create a widget, and use setCellWidget() and you're done.
If you have thousands of rows, then you're gonna have to draw the widgets yourself using QStyledItemDelegate, which will paint the widgets inside your QTableView. This is a very painful thing to do, but there's no way around it. The reasons you can find here.
I see at least three options to implement that in Qt:
Use a QtableView or QTableWidget and insert some custom controls in it. See comments made be other persons to your post
Use a QGridLayout and fill it with your controls by line and column
Make your own QWidget to store and manage the line elements (the spinbox, edit field, radio button) using a QHBoxLayout. You can design this in QtCreator, it can have it's own .ui. This could make it easy to handle the interaction between each QWidget of a line (directly handled by your QWidget class). Later, you can put an instance of it for every line you need in a QVBoxLayout.
Personnaly, I would go with the last option, but it may not work smartly if the controls of each line have different content/size (see comments), then first options should be prefered.

How to implement a Clickable Widget for QListView?

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 ;)

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.

Customize QListWidgetItem

I am creating my first app in QT and wanted to design a list. The listitem has two texts and one icon.
The problem is, i cant find any example or helping material, Only helping link i found is : Customize QListWidgetItem but i dont understand it. Although i have the same problem which this links points to...
What i understand is, i have two options:
1- Customize QListWidgetItem to use with QListWidget
2- Make some delegate to use with QListView
I was hoping to get started with option 1. Now in the link, some reply talks about "myItem" which is taking 2 texts as input. I want to know the implementation of "myItem".
In the link you posted, MyItem is just a normal QWidget. This means that you can create a widget in Qt Designer and then set that new widget you created as the widget that the QListWidgetItem should use for display. In the above example, MyItem takes two strings because there is a vertical layout with two labels in it (that's my assumption at least).
You should also note, and is discussed in the above link, that taking the approach of setting an item widget to use for every item in the list is an expensive thing to do in terms of performance and memory consumption. Because a QListWidget is a QListView, you can set an item delegate on it just like any other view and come out with a lighter weight solution (one instantiation of class vs. one instantiation for every item in your list)

How do I tell Qt to always show an editor in a QTableView?

I've got a QTableView for which I want to display the last column always in edit mode. (It's a QComboBox where the user should be able to always change the value.)
I think I've seen the solution in the Qt documentation, but I can't find it anymore. Is there a simple way of doing it?
I think I could archive this effect by using openPersistentEditor() for every cell, but I'm looking for a better way. (Like specifying it only one time for the whole column.)
One way to get the automatic editing behaviour is to call the view's setEditTriggers() function with the QAbstractItemView::AllEditTriggers value.
To display the contents of a given column in a certain way, take a look at QAbstractItemView::setItemDelegateForColumn(). This will let you specify a custom delegate just for those items that need it. However, it won't automatically create an editor widget for each of them (there could in principle be thousands of them), but you could use the delegate to render each item in a way that makes it look like an editor widget.
There are two possibilities:
Using setIndexWidget, but Trolltech writes:
This function should only be used to
display static content within the
visible area corresponding to an item
of data. If you want to display custom
dynamic content or implement a custom
editor widget, subclass QItemDelegate
instead.
(And it breaks the Model/View pattern…)
Or using a delegate's paint method. But here you have to implement everything like enabled/disabled elements yourself.
The QAbstractItemModel::flags virtual function is called to test if an item is editable (see Qt::ItemIsEditable). Take a look at Making the Model Editable in the Model/View Programming documentation.
I can't see an easy way to do this, but you might be able to manage by using a delegate. I honestly don't know exactly how it would work, but you should be able to get something working if you try hard enough. If you get a proper delegate, you should be able to set it on a whole view, one cell of a view, or just a column or row.

Resources