How to move programmatically to selected row in Qt? - qt

I use QTreeView and QSortFilterProxyModel
// Here I determine the index, that was saved before (_lastAddObjectIndex - QModelIndex)
QModelIndex next_index = _proxyModel->index(_lastAddObjectIndex.row(), 0);
// Here I select the row programmatically, and after that I'd like to move to that row (because table might have many rows)
view->selectionModel()->select(next_index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows | QItemSelectionModel::SelectCurrent);

I assume by moving, you mean scrolling. If so, you can achieve this by using this API:
view->scrollTo(next_index);
You can even change the scroll hint if you pass a second parameter to the method. This depends on whether you are happy with the default value, which just makes sure that the item is visible.
You can refer to the documentation for fine-tuning this behaviour further in case you need to.

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

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.

How to forbid equal indexes in QComboBoxes

I have got a number of QComboBoxes. Suppose that we have one combobox with index i and another combobox with index j. If user activate index j in the first combobox I want the second combobox index to be changed to i, so that there no equal indexes in all comboboxes. What is the easiest way to do it? I have tryed to do it with SIGNALS AND SLOTS approach:
for(int i=0;i<boxes.size();++i){
connect(boxes[i], SIGNAL(activated(int)),this,SLOT(boxIndexChanged(int)));
}
where boxes is a QList<QComboBox*> the problem here is that i don't know in slot function boxIndexChanged(int index) which combobox have emited signal(I need it in the case if there are identical indexes in two combobox).
You have at least two options:
Use QObject::sender() to get a pointer to object which emitted a signal. Please note, that it's a simple, but not recommended way (see method's documentation).
Use QSignalMapper.

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.

QTreeView: Setting all selected cells to the user-entered value at once

I have a QTreeView which has the ExtendedSelection attribute (users may select more than one non-contiguous range of cells).
I would like my app to allow them to select these multiple cells and then enter a value and have all the cells take that value.
My issue is that I don't know how to get the full range of cells passed to my model. Right now the index that is passed to the setData method is only the active cell, not the full range of selected cells.
In the past, I have had my view store the currently selected range in the model every time it changes, and then use that to control which cells to modify. This seems kind of hacky and I wonder whether anyone has a better and more elegant solution.
I am using PyQt by the way, though I suspect this applies to QT by itself.
Thanks!
I believe you can use selectionModel method of the QAbstractItemView class to iterate through selected indexes and change values of the corresponding cells. Below is a small example:
foreach (QModelIndex index, ui->treeView->selectionModel()->selectedIndexes())
{
qDebug() << "Changing index " << index.row();
ui->treeView->model()->setData(index, "new data");
}
hope this helps, regards

Resources