I am using QTableWidget and when the user clicks on a particular row, I use that index to perform some operation. I have also enabled sorting using setSortEnable, so when I sort it by clicking on a header, all row index change but I want previous index so what should I do?
I'm guessing you want the unsorted index so you can map that back to some external list of data? If that is the case, then you should use a QTableView() which will allow you to setup a sort proxy and map indexes back to your original data (model).
This question has some info that may help: Can't use itemFromIndex in clicked signal of QTreeView with QSortFilterProxyModel
Related
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;
}
I want to know how to change the order of QTableView rows by dragging, and store the order changes to the model?
I use QTableView as view and QSqlTableModel as model. I am using Qt 5.15.
I set:
ui->table_view->setSelectionMode(QAbstractItemView::SingleSelection);
ui->table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->table_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
Methods I tried:
1.
ui->table_view->setSectionsMovable(true);
ui->table_view->setDragEnabled(true);
ui->table_view->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->setAcceptDrops(true);
It doesn't take effect. The row cannot be dragged.
2.
ui->table_view->verticalHeader()->setSectionsMovable(true);
ui->table_view->verticalHeader()->setDragEnabled(true);
ui->table_view->verticalHeader()->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->verticalHeader()->setAcceptDrops(true);
The row can be dragged by vertical header. But the order of changes will not affect the model.
As far as I know the QTableView does not call moveRows method of the model by itself. Instead drag and drop actions call *mimeData methods.
So, one option would be the following:
In your model you need to implement mimeData and dropMimeData functions. When you drag and drop a row the view will ask for mimeData() of the given row. If you are sure that you need only internal moves you can encode the selected row indices to QMimeData. Then in the dropMimeData() you decode the indices that were selected and use them to call your moveRows() implementation. Return false from this function to prevent removing of the moved out rows.
Another option can be to override the QTableView methods such as dropEvent() in a way, that it calls the model moveRows() method directly.
Currently I want to update row items in a QStandardItemModel without losing the sort order and row selection in the respective QTableView.
I have tested two approaches:
Clearing the model by clear() and re-adding the rows "destroys" everything including headers.
Removing and re-adding all rows keeps the headers, but still "destroys" selection and sort order.
I could try to manually to a) remove all rows no longer required and then b) update the items of the changed rows. But is there no easier way?
I don't know, how you sorted your data before the update, but please take a look at the QTableView's sortByColumn() function.
As for the selection, if it still keeps disappearing, you can manually put back your selection, where it should be by:
// You access the selected index when the editing starts
QModelIndex index = table->selectionModel()->currentIndex();
//Later when you finished editing, you can select it again
table->selectionModel()->select(index, QItemSelectionModel::Select);
More about this:
QItemSelectionModel
QTableView
You can either remove the rows no longer required and add the new ones or manually remember the sort order and which items were selected before clearing. I.e. assign a unique ID (one can use setData() with a custom role for that), retrieve that before clearing from the selected items, and reapply the selection after recreating the items.
I want to know which header the user clicked on to give the currently sorted view.
Is there an API in flex framework that I can use to achieve this? Hopefully I can get back a column index so I know how it is currently sorted.
Thanks,
Mike
The mx.controls.DataGrid has a property named columns. Each column in this collection is an object of type mx.controls.dataGridClasses.DataGridColumn with a boolean property named sortDescending.
Otherwise, you can receive and handle the DataGrid event headerRelease. This event is transmitted when the user releases the mouse button on a column header, causing the column to become sorted.
How Can I find all the rows that has been changed in gridview. I can not use Ajax in any form
First get the contents of your grid before it was changed (such as caching the results of the original gridview datasource binding). Then go through the dataset/datatable/however you want to store it, and compare the contents with the current rows of the gridview.
There's no real efficient way to do this, no method like GridView.GetAllChangedRows(). So, what you might do instead is keep a behind the scenes List that you add to each time a row is modified (use the RowUpdated method), then clear this list when needed.
It depends upon how many columns you want to edit in a row.
If you have only one editable column in a row then you can associate a javascript method with that control which you want to modify and in that method you can get a rowid which you can save in another hidden field and in server side you can get all rows whose ids are stored in hidden field.
If you have whole row editable in that case the best approach I think you should save the original data source somewhere and also set a javascript method with rowclick event to get rowid which user selects. Then when user clicks on submit button get all rows whose row ids are stored in hidden field then compare those with same rowid in datasource. This is the best approach from my point of you.
Let me give you an example, suppose there are 1000 rows in a grid and user clicks on only 180 rows. In that case we will compare only 180 rows and wont compare rest of the rows.
Please let me know if somebody has better idea then this.