I have a small but quite annoying problem with Qt's QTableView
Since my view is used in a StackedLayout, I have to select a line based on a field in an other page (that part works ok).
So when I display this view, I select the line I want with a simple
QItemSelection selection = line2selection(line);
d_view->selectionModel()->select(selection, QItemSelectionModel::Select);
where line2selection creates a QItemSelection filled with all the indexes for the whole line.
As I sais, this part works ok, but introduce another problem:
When I do a shift+click to select several lines at once (which works great if I don't select a line "programatically"), it always stars the selection from the first line instead of the starting from the line currently selected.
Any idea how I could fix the problem?
btw, I tried to call the selectRow method on my view too, but doesn't seem to be much better...
add the QItemSelectionModel::Current flag to QItemSelectionModel::Select so the "current" item index is updated, this index acts as the anchor for the shift+click multi-selects
Related
I have a QTableView with 80+ columns displayed in it. The subclass i have created for QTableView allows has functionality for the standard table stuff i wanted e.g order by columns move columns and rows hide column and rows etc.
However the problem i have is the view's focus. lets say you have all the data in the table, you scroll all the way to the right so you are looking at columns 70-80 (assuming 10 columns fit on the screen at once) if i click the header of row 80 (to order by column 80) the table reorders (as expected) however it also jumps the view to the last focused cell (which as far as i can tell is the cell that was last clicked)
What i want to do is not necessarily refocus on the column that was clicked because this might still change the view what im looking for is to just keep the view's focus exactly as it is instead of having it jump back to where the last clicked cell was?
Is there some flag im missing for focus policy or will i need to get the current view and set the view back to that view after mouse clicks that reorder the table and if so how could this be done.
Im aware i have provided no code for this question but it doesnt seem there is any needed since its not a bug im looking to fix more of a feature im unaware of, if you want to see any just comment
EDIT:
Im using a QSortFilterPorxyModel, this seems to get set once (when i call this->setSortingEnabled(true); after the initial call to this on contruction my table model never calls sort again. I have a slot linked to the header clicked signal, and i set the scroll bars to scrollTo() to the index clicked, but i think the sort is happening after this so it does nothing, any idea of what signal are emitted after sorting so i can catch them and then set the view back maybe?
thanks
Before you do your sort, store the current values for where the scroll bars are with
int vPos = yourQTableView->verticalScrollBar()->sliderPosition();
int hPos = yourQTableView->horizontalScrollBar()->sliderPosition();
then after the sort, set it back
yourQTableView->verticalScrollBar()->setSliderPosition(vPos);
yourQTableView->horizontalScrollBar()->setSliderPosition(hPos);
The signals you are looking for are signals of QSortFilterProxyModel inherited from QAbstractItemModel:
layoutAboutToBeChanged()
layoutChanged()
I couldn't reproduce your symptoms by creating a QTableWidget, filling it up with random stuff, and then sorting a particular column. The selected cell stays selected, but does not become visible if it has scrolled off screen.
So the question is, what is causing the behavior you're seeing. It sounds as though scrollTo() is being called by some other function. Since that's a virtual function, I would override it with a pass-through function and see when it's getting called.
I found some problem.
I have class extended from CListCtrl. When I make double click on row I selected it. Everything good, but if I sort some column I have problem!
For example:
I have some row in second position. I selected it and sort column, highlighting is left on second position but my item has moved to 4th row (and selection moved to 4th row)
I have bad feeling that it could be some bug:(
Did somebody see problem like this?
PS: I'm not sure that I have to provide some code, because guess it's ok, but if needs it I will post it
Thank you very much and sorry for my English)
I've only seen this problem with owner data list views (LVS_OWNERDATA) so I'm guessing this is the case here. AFIK there are two possible solutions. The first is to store the selection state yourself and then use LVM_SETCALLBACKMASK to let the control know that you will provide the selection state. You will also have to respond to mouse clicks and update your data array. The other solution is to store a list of selected items before sorting, deselect all items, do the sorting and then finally restore the selection using the stored list.
I want to delete a selected row from the table when I click on the delete button.
But I can't find anything regarding deleting rows in the Qt documentation. Any ideas?
You can use the bool QAbstractItemModel::removeRow(int row, const QModelIndex & parent = QModelIndex()) functionality for this.
Here you can find an example for all this.
Also, here is an inline quote from that documentation:
removeRows()
Used to remove rows and the items of data they contain
from all types of model. Implementations must call beginRemoveRows()
before inserting new columns into any underlying data structures, and
call endRemoveRows() immediately afterwards.
The second part of the task would be to connect the button's clicked signal to the slot executing the removal for you.
If you are removing multiple rows you can run into some complications using the removeRow() call. This operates on the row index, so you need to remove rows from the bottom up to keep the row indices from shifting as you remove them. This is how I did it in PyQt, don't know C++ but I imagine it is quite similar:
rows = set()
for index in self.table.selectedIndexes():
rows.add(index.row())
for row in sorted(rows, reverse=True):
self.table.removeRow(row)
Works perfectly for me! However one thing to know, in my case this function gets called when a user clicks on a specific cell (which has a pushbutton with an 'X'). Unfortunately when they click on that pushbutton it deselects the row, which then prevents it from getting removed. To fix this I just captured the row of the sender and appended it to the "remove_list" at the very beginning, before the "for loops". That looks like this:
rows.add(self.table.indexAt(self.sender().pos()).row())
You can use another way by deleting the row from database, then clear the model and fill it again, this solution is also safe when you are removing multiple rows.
This question is to understand how to update any row programatically.
Details.
I have a listcrtl, that accepts the data from either from a file or from the edit controls in the dialog. When the items are added I will know its position, that I added, so I can change its subitem texts. I have even implemented the sort functionality in the list, so now the position keeps changing. I have an identifier column for each row, so that I can recognize the row.
Now, from an out side event, if I have to change an other columns value of an ID that I know , I have to first find the position of the item by comparing the id column, then with that position, I have set the subitemtext.
This works fine except that it takes time to find the row first then it need to update the column.
Now, in order to get the row directly, I need some help.
I have gone through
http://msdn.microsoft.com/en-us/library/windows/desktop/hh298346(v=vs.85).aspx
But this does not use MFC. Please help me achieving this.
If you have many items you should consider switching to Virtual Lists. It is the fastest way to access the data. If you do not want to invest time to this, then the easiest way for you will be the following:
When you populate the CListCtrl store the ID of each item in the item data using the SetItemData() method. The ID will always be associated with the item, even after re-sorting.
When you need to locate the required item, just scan all items, but do not use GetItemText(). Use GetItemData() instead. This will be faster
Does anyone know how to un-highlight a previously selected line in an MFC CListCtrl programmatically ?
To de-select the 20th item:
YourListCtrl.SetItemState(20, 0, LVIS_SELECTED);
Well, it doesn't work if the the List view is Report style ie multiple columns. Do you have any solution for that?
One can set the List property as:
m_ctlList.SetExtendedStyle(LVS_EX_FULLROWSELECT);
which always selects the particular line when user clicks on that line, but if programmer deletes a line in the list view, the next row replaces the selected one and the row is un-highlighted.