-
Notifications
You must be signed in to change notification settings - Fork 10
Description
Hi,
I'm grateful for your work. Allowing async/await in wxPython is great.
Unfortunately, while testing, I find a pretty strange sluggishness which I'm unable to explain. Is it because I'm running on Windows? Or because I'm using only the keyboard (as a screen reader users)? Keyboard events would generate and I can understand, for every key I press, four or five events could be sent... actually more than that. Still, that doesn't sound like a lot of event. Yet, I find a performance of about 200ms each time I press a key, enough to be perceptible. I've simplified your example to a very simple window with only three widgets (two list boxes and one text entry). You can see the problem when typing quickly in the text area, or when changing from widget to widget using the tab key (not the mouse).
import wx
import time
from wxasync import AsyncBind, WxAsyncApp, StartCoroutine
import asyncio
from asyncio.events import get_event_loop
ASYNC_VERSION = True
class BasicFrame(wx.Frame):
def __init__(self, parent=None, id=-1, title=""):
wx.Frame.__init__(self, parent, id, title, size=(800,800))
self.wx_panel = wx.Panel(self)
self.wx_sizer = wx.BoxSizer(wx.VERTICAL)
self.left = wx.ListBox(self.wx_panel, name="list1")
self.wx_sizer.Add(self.left)
self.right = wx.ListBox(self.wx_panel, name="list2")
self.wx_sizer.Add(self.right)
self.text = wx.TextCtrl(self.wx_panel, name="Username")
self.wx_sizer.Add(self.text)
self.wx_panel.SetSizerAndFit(self.wx_sizer)
# Fills the lists
self.left.Append("One")
self.left.Append("Two")
self.left.Append("Three")
self.right.Append("First")
self.right.Append("Second")
def main():
class MyApp(wx.App):
def OnInit(self):
frame = BasicFrame(title="test")
frame.Show(True)
self.SetTopWindow(frame)
return True
app = MyApp(0)
app.MainLoop()
# del app
def main_async():
# see https://github.com/sirk390/wxasync
app = WxAsyncApp()
frame = BasicFrame(title="test")
frame.Show(True)
app.SetTopWindow(frame)
loop = get_event_loop()
loop.run_until_complete(app.MainLoop())
if __name__ == "__main__":
if ASYNC_VERSION:
main_async()
else:
main()What's causing this delay? I'm not sure. Obviously, if decreasing asyncio.sleep in the main loop to something smaller, this lag decreases and slowly (incredibly slowly) disappears if a small value is set. But then the problem of a small value is the CPU goes up and up to compensate. Lots of overhead. So I was puzzling over this problem and I still don't find a solution. Obviously, it would be helpful if the loop could instead send its events to be processed to an asynchronous loop, for instance. The coroutine responsible for reading the loop would just block until an event is available. But we're still dealing with the same problem: wxPython and another event loop don't get along so well, except if you don't mind the CPU overhead.
But from seeing the code I can't decide what's causing the delay in particular. 5ms for a sleep is definitely not huge. Again, a key press (particularly the tab key which encourages to switch between widgets, hence triggering lots of events) might fire tens of events... but that's still not enough, in theory, to be perceptible by the user. Any help on this would be appreciated!
Thanks in advance,
Vincent