sirk390 / wxasync

asyncio support for wxpython
MIT License
77 stars 9 forks source link

Use of asyncio Streams combined with wxPython #18

Closed bastien34 closed 2 years ago

bastien34 commented 2 years ago

First of all, I'm not posting here an issue. Would it be possible to add an example of a dialog initiated along with a Stream server? I'm struggling to create a GUI that would be able to communicate via an other process. I think that asyncio Streams would feat nicely with my project but I have no clue how to start a server and make the window listening to external events. I'm posting here, because it sounds strange but resources about wxPython and this commun usage are quite rare.

sirk390 commented 2 years ago

Hi Bastien,

Have a look at something like this:

from wxasync import AsyncBind, WxAsyncApp, StartCoroutine
import asyncio
from asyncio.events import get_event_loop
import time

class TestFrame(wx.Frame):
    def __init__(self, parent=None):
        super(TestFrame, self).__init__(parent)
        vbox = wx.BoxSizer(wx.VERTICAL)
        self.logctrl =  wx.TextCtrl(self, style=wx.TE_MULTILINE)
        vbox.AddStretchSpacer(1)
        vbox.Add(self.logctrl, 1, wx.EXPAND|wx.ALL)
        self.SetSizer(vbox)
        self.Layout()
        StartCoroutine(self.run_server, self)

    def log(self, text):
        self.logctrl.AppendText(text + "\r\n")

    async def handle_connection(self, reader, writer):
        data = await reader.read(100)
        message = data.decode()
        addr = writer.get_extra_info('peername')
        self.log(f"Received {message!r} from {addr!r}")
        self.log(f"Send: {message!r}")
        writer.write(data)
        await writer.drain()
        self.log("Close the connection")
        writer.close()

    async def run_server(self):
        server = await asyncio.start_server(self.handle_connection, '127.0.0.1', 8888)

        addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
        self.log(f'Serving on {addrs}')

        async with server:
            await server.serve_forever()

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

asyncio.run(main())

Does that answer your question?

bastien34 commented 2 years ago

Thanks a lot for your answer which is absolutely working.

Unfortunately, I need to use it from a LibreOffice extension where there is no async. So I use socket, it seemed to work but after a first attempt, I got a broken pipe. Anyway, this is out of my initial request.

You really should add this example to the repo ! :-)

sirk390 commented 2 years ago

It've added it as example. Thanks for the tip! I'll close this issue