Hi all,
I'd like to ask for some advice regarding long running GUI operations,
especially the possibility to cancel them cleanly if necessary.
The examples and discussions I could find seem all to deal with
non-GUI long running tasks, which shouldn't block the user interface.
In my current case, it is typically the highlighting the search
results (in bold) in a TextCtrl widget. The SetStyle calls are
probably the slowest part in my app, but for the most cases I am ok
with it;
however, it can happen (by using a bad, i.e. too general search
pattern), that there are too much places to be highlighted (like
several tens of thousands), which would take minutes to finish on my
older laptop. In this case I'd eventually like to abort the
highlighting and leave the displayed text unchanged and the program in
the previous "responsive" state.
Is it possible to run such GUI-intensive tasks in a way, that the GUI
can still accept clicks/ escape key etc. to stop the time consuming
operation of itself?
Could someone possibly point me to some documentation or code examples
regarding this?
Thank you very much in advance,
regards,
Vlastimil Brom
If you use a progress bar, (wx.ProgressDialog or better PyProgress),
with a cancel button on in that you periodically update and check the
return value then you can easily do this, e.g. Something along the lines of:
def HighlightEntries(self):
style = wx.PD_APP_MODA | wx.PD_ELAPSED_TIME | wx.PD_CAN_ABORT
dlg = PP.PyProgress(None, -1, "Highlighting Enries",
"Press Cancel to
Abort",
agwStyle=style)
KeepGoing = True
while KeepGoing:
KeepGoing = self.ProcessNextTen() # Process 10 entries and
return True if finished
KeepGoing = KeepGoing and dlg.UpdatePulse()
dlg.Destroy()
wx.SafeYield()
wx.GetApp().GetTopWindow().Raise()
···
On 24/07/2012 10:08 AM, Vlastimil Brom wrote:
Hi all,
I'd like to ask for some advice regarding long running GUI operations,
especially the possibility to cancel them cleanly if necessary.
The examples and discussions I could find seem all to deal with
non-GUI long running tasks, which shouldn't block the user interface.
In my current case, it is typically the highlighting the search
results (in bold) in a TextCtrl widget. The SetStyle calls are
probably the slowest part in my app, but for the most cases I am ok
with it;
however, it can happen (by using a bad, i.e. too general search
pattern), that there are too much places to be highlighted (like
several tens of thousands), which would take minutes to finish on my
older laptop. In this case I'd eventually like to abort the
highlighting and leave the displayed text unchanged and the program in
the previous "responsive" state.
Is it possible to run such GUI-intensive tasks in a way, that the GUI
can still accept clicks/ escape key etc. to stop the time consuming
operation of itself?
Could someone possibly point me to some documentation or code examples
regarding this?
Thank you very much in advance,
regards,
Vlastimil Brom
Hi,
thank you very much for the excellent suggestion! I didn't thought of
a progress dialog, and it was really straightforward to add to the
existing code (a for loop, which only needed an added break.
Only o slight change was needed for wx.ProgressDialog, namely:
... dlg.UpdatePulse()[0]
as this method apparently returns a tuple of two booleans: (continue, skip);
this is probably different from PyProgress?
(I plan to eventually adapt the app for agw, but for now it uses the
"conventional" widgets.)
Thanks again, I really didn't expect to get this functionality in
under ten lines of code!
regards,
vbr
My (clumsy, not style-conform) code ended up like this:
# # # # # # # # # # # # # # # # # # # # # # #
def set_text_style(self, which_widget, which_style, indices=,
base_style= wx.TextAttr()):
"""
Apply the style to a TextCtrl widget between the given text indices.
indices format, e.g.: indices=[[4,7],[18,29],...]
Long running operation can be cancelled from the progress dialog.
"""
dlg = wx.ProgressDialog(u"Highlighting matches", u"The matches
are being highlighted, press cancel to abort this operation.",
maximum=len(indices), parent=self,
style=0|wx.PD_APP_MODAL|wx.PD_CAN_ABORT|wx.PD_AUTO_HIDE)
should_continue = True
count = 0
for start_idx, end_idx in indices:
count += 1
should_continue = which_widget.SetStyle(start_idx,
end_idx, wx.TextAttr.Combine(which_style, base_style, None))
should_continue = should_continue and dlg.UpdatePulse()[0]
dlg.Update(count)
wx.SafeYield()
if not should_continue:
break
dlg.Destroy()
wx.SafeYield()
# # # # # # # # # # # # # # # # # # # # # # #
···
2012/7/24 Gadget/Steve <GadgetSteve@live.co.uk>:
On 24/07/2012 10:08 AM, Vlastimil Brom wrote:
Hi all,
I'd like to ask for some advice regarding long running GUI operations,
especially the possibility to cancel them cleanly if necessary.
The examples and discussions I could find seem all to deal with
non-GUI long running tasks, which shouldn't block the user interface.
In my current case, it is typically the highlighting the search
results (in bold) in a TextCtrl widget. The SetStyle calls are
probably the slowest part in my app, but for the most cases I am ok
with it;
however, it can happen (by using a bad, i.e. too general search
pattern), that there are too much places to be highlighted (like
several tens of thousands), which would take minutes to finish on my
older laptop. In this case I'd eventually like to abort the
highlighting and leave the displayed text unchanged and the program in
the previous "responsive" state.
Is it possible to run such GUI-intensive tasks in a way, that the GUI
can still accept clicks/ escape key etc. to stop the time consuming
operation of itself?
Could someone possibly point me to some documentation or code examples
regarding this?
Thank you very much in advance,
regards,
Vlastimil Brom
If you use a progress bar, (wx.ProgressDialog or better PyProgress),
with a cancel button on in that you periodically update and check the
return value then you can easily do this, e.g. Something along the lines of:
def HighlightEntries(self):
style = wx.PD_APP_MODA | wx.PD_ELAPSED_TIME | wx.PD_CAN_ABORT
dlg = PP.PyProgress(None, -1, "Highlighting Enries",
"Press Cancel to
Abort",
agwStyle=style)
KeepGoing = True
while KeepGoing:
KeepGoing = self.ProcessNextTen() # Process 10 entries and
return True if finished
KeepGoing = KeepGoing and dlg.UpdatePulse()
dlg.Destroy()
wx.SafeYield()
wx.GetApp().GetTopWindow().Raise()
--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en