Find and highlight a specific row in tableview
-
I created my project by modifying the Custom Sort / Filter model example, so if anyone would give me code that works there, it should be easy for me to do it in my actual program.
One row in the Sorted / Filtered display has a value in the Sender column that starts with lower-case p. I seek example code to add between the calls to window.show() and app.exec() in main(), that will locate and highlight that row.
As it happens, that particular "target" row isn't initially visible, so before I can "manually" highlight it, I have to scroll the display. If I can programmatically move the focus, I'll need to ensure the newly-highlighted line is in fact visible in the TableView.
-
@FumbleFingers
You access values in a table model viadata(index)
for a givenQModelIndex index
. If you go through the source model you will visit rows in the order they were added/received. If you go through the sort proxy model you will visit them in whatever order the proxy shows/is sorted on, which is the order they are displayed in theQTreeView
using that as its model.To find your "p". Let's say that the Sender column is the first column (#0) in the model and you go via the proxy; here's a suitable function to return the row number of the first
p
encountered:for (int i = 0; i < proxy->rowCount(); i++) { QModelIndex index = proxy->index(i, 0); QString sender = index.data().toString(); if (sender.startsWith('p')) return i; } return -1;
You will want to call this some time after you have set up model and proxy and filled with data. Doubtless in the long run you will want to call this from some slot, in response to the user typing or clicking something.
-
@FumbleFingers
void QTableView::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint = EnsureVisible) can be used to scroll to the desired model index.You can search the sorted proxy model's indexes to find the first one whose Sender column starts with a letter.
-
@JonB: Many thanks. I already "kinda" knew how to ensure some specific row is visible, because I successfully subclassed myTreeView(), within which my selectionChanged() override function calls scrollTo(). The other parameter for that call is treeView.currentIndex(), which already exists (I've no idea how to create one of those for myself, even if I knew which 'row' I wanted).
I haven't looked at "table search" functions yet. It's getting late where I am (UK), but I'll have a look tomorrow. Fingers crossed, a successful search will create the index object I need to pass in the scrollTo() call.
-
@JonB I've just spent another hour unsuccessfully trying to discover how to search a QT table, but I'm no further forward. I've spent the odd hour or two looking at this problem several times over many weeks, so the one thing I can be quite sure of is I'll never be a QT expert! It's hard!
The learning curve for QT is incredibly steep, but I'm still hoping you (or someone) can give me a few lines of actual code to execute between window.show() and app.exec() in the main() function of the Custom Sort / Filter model example. If I could just see some actual C++ code that fits the example, I'm sure I could adapt it to my exact situation.
I assume that what I want to do must be done within the Window class object, so I guess the code I'm asking for wouldn't actually go in the main() function itself.
That's to say - I think I'm asking for code to append to Window.setSourceModel() - by which time the actual data has been loaded somewhere, and can be searched for a row where Sender starts with 'p'.
-
@FumbleFingers
You access values in a table model viadata(index)
for a givenQModelIndex index
. If you go through the source model you will visit rows in the order they were added/received. If you go through the sort proxy model you will visit them in whatever order the proxy shows/is sorted on, which is the order they are displayed in theQTreeView
using that as its model.To find your "p". Let's say that the Sender column is the first column (#0) in the model and you go via the proxy; here's a suitable function to return the row number of the first
p
encountered:for (int i = 0; i < proxy->rowCount(); i++) { QModelIndex index = proxy->index(i, 0); QString sender = index.data().toString(); if (sender.startsWith('p')) return i; } return -1;
You will want to call this some time after you have set up model and proxy and filled with data. Doubtless in the long run you will want to call this from some slot, in response to the user typing or clicking something.
-
-
@JonB That's absolutely marvelous! Thank you so much!
I've successfully adapted your example code for my exact situation, and it works perfectly. I vaguely understand your point about using 'slots' in future, and hopefully I'll eventually have reason to do something like that. But for the time being all I want to do is unilaterally set my initial TableView focus to some record just added to my database by an external program (which writes the UniqueID of that record into a configuration settings file that my program reads on startup).
Once again, many thanks for your help.
-
For completeness, here's the window::refocus() I call between window.show() and app.exec() in the main() function of the Custom Sort / Filter model example...
void Window::refocus(void) { QModelIndex idx; for (int ct = proxyModel->rowCount(proxyView->currentIndex().parent()); --ct>=0; ) if (proxyModel->data(idx=proxyModel->index(ct, 1, QModelIndex()), 0).toString().left(1)=="p") { proxyView->scrollTo(idx, QTreeView::PositionAtCenter); proxyView->setCurrentIndex(idx); } }
It may not be everyone's favourite coding style, but it works for me.
-
@FumbleFingers said in Find and highlight a specific row in tableview:
It may not be everyone's favourite coding style, but it works for me.
Umm, you assign to
idx
in the middle of passing a parameter, and then use it afterwards!? :)