Qt QListView with different delegates per column - qt

The Delegate system is not clear to me by now.
I have a QListView properly displaying my custom model.
My model is composed by the following columns:
Column 1, 2 and 3 are a Text column, the column's item's text is filled using QAbstractItem::setText();
Column 4, 5, 6 and 7 are a QVariant of a custom class. These column have items filled with QAbstractItem::setData(QVariant::fromValue(MyCustomClass());
What I need from the QListView is it to display the text on the column 1,2 and 3, and display a custom QString obtained by a method of MyCustomClass on clumns 4,5,6 and 7.
How can I achieve that?

Use QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelegate* delegate), docs.
Have you got a custom model? If all you are pulling out of your custom data is text, it would be easier to reimplement QAbstractItemModel::data(const QModelIndex& index, int role) const, query which column index is, and if it is your custom data column return the display role with the custom data text; otherwise just call the parent implementation.

Related

Hide column in QAbstractTableModel

I have a self created Qt-Model derieved by QAbstractTableModel. The data behind the model contains multiple QUuid-columns, whose cell-data I need to pass around the application. Due to design-reasons I don't want to show the QUuid-columns to the user, but keep them in the background to always guarantee access to the needed id-columns.
The data is bound to a Qtitan TableView Grid, where I can hide the column, but not totally remove it from the view. I can always reenable the visability which is not what I want.
So my question is if there are any options from the Qt-Model-side to hide a column or to avoid binding it to the view and just keep the data in the background.
You can subtract those columns from the visible columns by returning the column respectively in columnCount.
This would require to either move them to the end, or map the user visible column count to the underlying columns in your data() implementation.
It is probably a bit simpler to move those invisible columns to the end to avoid the mapping, but you can also do the mapping if you like.
int MyModel::columnCount(const QModelIndex& parent) const
{
return allColumns - columnsToHide;
}

Custom Model for TableView or QStandardItemModel

I want to create a TableView with two columns:
The first one for a parameter name
The second one with the parameter value, which could be a float, bool, int or a string
The second column should be editable, and a bool should be represented by a checkbox. For this model, should I subclass QAbstractItemModel or would the QStandardItemModel be fitting? Also, should one item have the two properties name and value, or should this be better seperated into two items?
It depends on your subject field. If you have big number of parameters then you should subclass QAbstractItemModel, because in the other case time of data view will be significant, if not QStandardItemModel is quite simple for this purpose.

How do I Insert an item at top of QTreeView

In my app I'd like to insert an item at the top of a QTreeView.
What I have so far will insert an item just above the currently selected item. The code (nicked, I think, from the EditableTreeviewDemo):
QModelIndex index = this->selectionModel()->currentIndex();
QAbstractItemModel *model = this->model();
if (!model->insertRow(index.row(), index.parent()))
return;
I guess what I need is the index to the current first row? How do I get this?
As a side question, what happens to the current index when a row is inserted? Does it continue to point to the same item, or the same row?
Well first you have to know that insertRow is a function from QAbstractItemModel and it will call insertRows (with an s). This function must be redefined in your model subclass if you want to allow insertion of data in your model.
http://doc.qt.io/qt-5/qabstractitemmodel.html#insertRows
Also consider that any parent of a topmost index is a invalid QModelIndex. Then the call to do would be :
model->insertRow(0, QModelIndex());
And because this is the default value for the second parameter, simply call :
model->insertRow(0);
Then in your redefinition of insertRows simply check the validity of you parent index to ensure you news underlying data is created where you want it to be.
For you question, inserting data in the model won't affect the current and selected items.

QT: QTableView read cell content

I'm writing a small program with QT creator (QT 5.2.1) under Windows 7 (32 bit) and I'm having problems reading the informations stored in a TableView. My application has 3 elements, a TableView to store text data, a TextBrowser to show info and a buttom.
I modified the TableView properties: when the user selects with the mouse a cell, the full row is selected and multiple row selection is not allowed.
The user select a row and when the buttom is pressed, I would like to read the content of a specific TableView cell and show it in a TextBrowser. In particular, I would like to know the row index of the selected row and read the content of the cell with that row index and a specific column index (example 2).
The pseudo-code is this:
void my_program::on_pushButton_clicked()
{
ui->textBrowser->append("button pressed");
QItemSelectionModel *select = ui->tableView->selectionModel();
int index_row = select->selectedRows();
int index_column = 2;
char cell_data[30] = ??[index_row][index_column]
ui->textBrowser->append(cell_data);
}
The main problem is that select->selectedRows() returns a QModelIndex that is a collection of indexs and I do not know how to convert it to int (since multiple selection are not allowed, it should have only one element).
I would be glad if someone can suggest me a way to proceed.
Thanks
Francesco
edit:
Hi Bogdan, thanks a lot!! I succeed to read the cell content by using
ui->textBrowser->append(ui->tableView->model()->data(ui->tableView->model()->index(2,5)).toString());
this give me the content of the cell in position 2,5.
not sure if this is the best way or not but it works !!.
Can you be a bit more precise about how to iterate the QModeIndexList ? thanks :)
selectedRows() returns QModelIndexList, thus you need to iterate over it and call QModelIndex::data() to get stored data.

Different Qt::CheckStateRole for different views?

Currently I have a simple setup where I maintain a list of bools corresponding to each item in my ListModel:
http://programmingexamples.net/wiki/Qt/ModelView/StringListModelCheckable
However, now what I want to do is have two such lists bools, say IsHot and IsLarge. Then I want to have a ListView that displays each string with a checkbox for one of the bools (the "Hot" view), and a separate ListView that displays each string with a checkbox for the other bool (the "Large" bool). Any hints on how to go about this?
Make your model a table, return the data in two different columns, the cells in these columns will be checkable.
On your list views, call QListView::setModelColumn to set the column the list view displays.
If you want to synchronise scrolling between the lists, you would then be better using a QTableView, so that rows would match up.
Edit to add more detail on returning text and check state.
To return a text and the state of a checkbox from the model you return different data for different roles from the [data] function on your model.
From the manual for Qt::ItemDataRole:
Qt::DisplayRole The key data to be rendered in the form of text. (QString)
Qt::CheckStateRole This role is used to obtain the checked state of an item. (Qt::CheckState)
Both columns in your model would return the same data (the name) for DisplayRole but different data for CheckStateRole

Resources