Skip to main content

Async I/O bridge for wxPython — run asyncio coroutines with wx GUI

Project description

aiowx

asyncio support for wxPython

aiowx is a library for using Python 3 asyncio (async/await) with wxPython. The library polls UI messages every 20ms and runs the asyncio message loop the rest of the time. When idle, the CPU usage is 0% on Windows and about 1-2% on macOS.

Installation

pip install aiowx

Install using:

pip install aiowx

Usage

Create a WxAsyncApp instead of a wx.App

app = WxAsyncApp()

and use AsyncBind to bind an event to a coroutine.

async def async_callback():
    (...your code...)
    
AsyncBind(wx.EVT_BUTTON, async_callback, button1)

You can still use wx.Bind together with AsyncBind.

If you don't want to wait for an event, you just use StartCoroutine and it will be executed immediatly. It will return an asyncio.Task in case you need to cancel it.

task = StartCoroutine(update_clock_coroutine, frame)

If you need to stop it run:

task.cancel()

Any coroutine started using AsyncBind or using StartCoroutine is attached to a wx.Window. It is automatically cancelled when the Window is destroyed. This makes it easier to use, as you don't need to take care of cancelling them yourselve.

To show a Dialog, use AsyncShowDialog or AsyncShowDialogModal. This allows to use 'await' to wait until the dialog completes. Don't use dlg.ShowModal() directly as it would block the event loop.

You start the application using:

await app.MainLoop()

Below is full example with AsyncBind, WxAsyncApp, and StartCoroutine:

import wx
from aiowx import AsyncBind, WxAsyncApp, StartCoroutine
import asyncio
import time


class TestFrame(wx.Frame):
    def __init__(self, parent=None):
        super(TestFrame, self).__init__(parent)
        vbox = wx.BoxSizer(wx.VERTICAL)
        button1 =  wx.Button(self, label="Submit")
        self.edit =  wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ST_NO_AUTORESIZE)
        self.edit_timer =  wx.StaticText(self, style=wx.ALIGN_CENTRE_HORIZONTAL|wx.ST_NO_AUTORESIZE)
        vbox.Add(button1, 2, wx.EXPAND|wx.ALL)
        vbox.AddStretchSpacer(1)
        vbox.Add(self.edit, 1, wx.EXPAND|wx.ALL)
        vbox.Add(self.edit_timer, 1, wx.EXPAND|wx.ALL)
        self.SetSizer(vbox)
        self.Layout()
        AsyncBind(wx.EVT_BUTTON, self.async_callback, button1)
        StartCoroutine(self.update_clock, self)
        
    async def async_callback(self, event):
        self.edit.SetLabel("Button clicked")
        await asyncio.sleep(1)
        self.edit.SetLabel("Working")
        await asyncio.sleep(1)
        self.edit.SetLabel("Completed")

    async def update_clock(self):
        while True:
            self.edit_timer.SetLabel(time.strftime('%H:%M:%S'))
            await asyncio.sleep(0.5)


async def main():            
    app = WxAsyncApp()
    frame = TestFrame()
    frame.Show()
    app.SetTopWindow(frame)
    await app.MainLoop()


asyncio.run(main())

Performance

Below is view of the performances (on windows Core I7-7700K 4.2Ghz):

Scenario Latency Latency (at max throughput) Max Throughput(msg/s)
asyncio only (for reference) 0ms 17ms 571 325
wx only (for reference) 0ms 19ms 94 591
aiowx (GUI) 5ms 19ms 52 304
aiowx (GUI+asyncio) 5ms GUI / 0ms asyncio 24ms GUI / 12ms asyncio 40 302 GUI + 134 000 asyncio

The performance tests are included in the 'test' directory.

Repository

https://github.com/Row0902/aiowx

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aiowx-0.1.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aiowx-0.1.0-py3-none-any.whl (6.5 kB view details)

Uploaded Python 3

File details

Details for the file aiowx-0.1.0.tar.gz.

File metadata

  • Download URL: aiowx-0.1.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for aiowx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 708acc4c0667e0efbc159abe8d9279399b1e2607c82ebb97cf2d3edbfeea7b3e
MD5 661b2a1fd1aa522e57a0bc63d7e35cdd
BLAKE2b-256 53e762aa1b6da2b3a24ad6af34f6e7e9daaa9aa44479f951e3e8ff3e676b1a56

See more details on using hashes here.

File details

Details for the file aiowx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aiowx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for aiowx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f7e9448d4909fa58e0384fe842fb427558da5621e958c9c94e9837681a8f0002
MD5 ede727bb398b5807726ef714580ab074
BLAKE2b-256 0a144cd2cea2f3e807dab51930d1cd84c9384621be02d04fc0d183b3f260ec3c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page