My Qt-Application (currently on PySide2 (Qt 5.15.6)) uses QTreeViews and appropriate Models to show big hierarchical structures, some of them really deep and/or containing reference loops. For displaying only nodes that match a given QRegExp I derived QSortFilterProxyModel
and reimplemented filterAcceptsRow
to decide if a node should be displayed. In case a node doesn't match the RegExp, I walk down recursively to check if any of its' descendants match... more or less that's shown in the code below.
def filterAcceptsRow( self, row, parent ):
def _match( index ):
return regExp.exactMatch( pathOf(index) )
def _check( *indices ):
return any( _match(idx) for idx in indices ) or \
any( _walk(idx) for idx in indices )
def _walk( index ):# . o O (how to determine that break was requested?)
if _breakRequested(): return False
else : return any( _check(idx) for idx in childrenOf(index) )
return _check( indexOf( row, col, parent )
This works usually quite well and (with some optimization) fast. However, in case of a deep tree structure and a careless user input the recursive descent might take a while what is leading to a blocked GUI.
So long story short: Is there any way of aborting an intensive GUI update (like here filtering nodes) by e.g. pressing ESC?
Here some thoughts and/or what I tried so far...
- Since
filterAcceptsRow
is called from Qt for updating the GUI I guess I can't really shift it to some worker thread, right? Well, I tried and it ended fatally ... :-S - In the dummy code above I put a call to
_breakRequested()
where I would ask for a break request. But how would such function look like? - Since we're right in processing some Event that led to our filtering the event loop is blocked and can't register any key strokes, right?
- Calling
processEvents()
here (in order to detect key strokes) would mix the processing order of events. According to the try I gave it, bad idea :-(.
I searched and tried a lot of different approaches, without luck. Am I really the only one who wants to escape from a blocked GUI while the blocking part can't be shifted to another thread?
- Basically I don't need to (and must not) process the events at that point (
_breakRequested()
). I would be fine with an event look ahead by sneaking along the event queue and looking for an according key event. However this doesn't seem possible in Qt before version 6. - Even if it was possible, is Qt registering Events (adding them to the event queue) between subsequent calls to
filterAcceptsRow
? Is there something likequeueEvents()
without processing them? - While the GUI is busy, is it possible to open another (modal) Widget with its' own thread and event loop listening for key strokes?
Sorry if this all is just bullshit but as you see, I got a bit stuck ... can somebody show me the light, please?