Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
Manually refresh QListWidget while inserting
I'm currently adding a huge list of items in my QListWidget, the process takes approximately from 5 to 10 secs.
I would like to manually refresh the new items in the widget to show the "progress", how can I efficiently do it? Apparently, calling
udpaterefreshes all the items, so it takes more time as there is more items, and the widget refreshes itself when it comes back to the event loop.
While I'm adding the items to the list, I'm using a recursive call, so I won't return to the event loop before the end.
If possible, I would like to add an item and refresh the last item to be shown, and so on (or maybe each 5 items, for instance).
VRonin last edited by
You can simply call
@VRonin Thank you for the hint. It works almost as expected. The scrollbar shrinks but the widget stays empty. But when I focus on another app or refocus on mine, the content on the widget flashes and disappears again.
Is it related to the speed of insertion? Is there a last thing missing?
How many items are you trying to add ?
Doing so you will be able to implement smarter algorithm to handle injection of big amount of data like batch insertion maybe a bit of thread to offload the work from the main thread etc.
Hope it helps
Max13 last edited by Max13
@SGaist Thanks for the suggestion. Currently, I'm adding as much directories and files in a selected folder on the computer. So it can be from 1 to ... elements.
Before subclassing all that, I made another class which receives the
QListWidgetand has a
crawlmethod. When crawling, I tried to call:
QtConcurrent::run(crawler, &Crawler::crawl), which works correctly but still freezes the GUI. Is that what you suggested?
EDIT: BTW, I'm adding them by creating
QListWidgetItems 1 by 1.
I was using
QFuture<T>::waitForFinished()which was blocking the main thread. I now send a signal when it's finished and return peacefully to the main loop.
I'm still unable to see the changes in the list, live. Doing a refresh (using
QApplication::processEvents()) will refresh all the list, is it possible to only "commit" the last added element?
Why not use a QFileSystemModel ?
@SGaist Because I think it would be more expensive to use this model then parse it searching for what I have to hide. So I thought, it would be faster to just recursively parse the filesystem myself and immediately sort what I need to keep or hide. Isn't it?
You can add custom QSortFilterProxyModel that will remove what you don't want.
@SGaist Actually, "sorting" here means I have to exclude considering characteristics, like filename length. For real, is it heavier to feed the widget myself, than using the Model, View and sorter?
If you say so, as a forgotten Qt Ambassador I can only trust a permanent Qt Champion ;)
But I still would like to know what's the problem with my code. Anyway, I will look for the issue later
It's rather the filter part that is interesting in that class for your use case.
Not knowing your code I can't comment ;)
Finally... After few docs and experiences, I don't know how but I missed the fact that
QWidgets are not reentrant (thanks to @kshegunov), and I also missed the fact that signals and slots are made for that.
@SGaist So, thanks for your advices but doing real MVC made my app too complicated for what it does. In a more constructed project, I would do what you suggested. I've simplified mine:
- Choose your "root" directory
Crawlercrawls (recursively in
Qt::Concurrent) and send a signal when the
QFileInfo::fileName().length()is more than x characters
- A slot in the
MainWidgetadds the item in the
That's all for now (auto-rename for later), so few lines of code. Thank you for your advices.