【问题标题】:Running asyncio bot concurrently to Tkinter GUI同时运行 asyncio bot 到 Tkinter GUI
【发布时间】:2020-07-19 09:35:03
【问题描述】:

我正在尝试将 Python Twitch 机器人 (https://github.com/TwitchIO/TwitchIO) 集成到 Tkinter GUI 中。这是我从twitch.io.ext.commands.bot 子类化的机器人

import os

from twitchio.ext import commands
from dotenv import load_dotenv
from os.path import join, dirname

class Bot(commands.Bot):

    def __init__(self):

        dir_path = os.path.dirname(os.path.realpath(__file__))
        dotenv_path = join(dir_path, '.env')
        load_dotenv(dotenv_path)

        TMI_TOKEN = os.environ.get('TMI_TOKEN')
        CLIENT_ID = os.environ.get('CLIENT_ID')
        BOT_NICK = os.environ.get('BOT_NICK')
        BOT_PREFIX = os.environ.get('BOT_PREFIX')
        CHANNEL = os.environ.get('CHANNEL')

        super().__init__(irc_token=TMI_TOKEN,
                         client_id=CLIENT_ID,
                         nick=BOT_NICK,
                         prefix=BOT_PREFIX,
                         initial_channels=[CHANNEL])


    async def start(self):
        await self._ws._connect()

        try:
            await self._ws._listen()
        except KeyboardInterrupt:
            pass
        finally:
            self._ws.teardown()


    async def stop(self):
        self._ws.teardown()


    async def event_ready(self):
        print("ready")


    async def event_message(self, message):
        print(message.content)
        await self.handle_commands(message)


    @commands.command(name='test')
    async def my_command(self, ctx):
        await ctx.send(f'Hello {ctx.author.name}!')

这是 Tkinter 图形用户界面

try:
    import Tkinter as Tk
except ModuleNotFoundError:
    import tkinter as Tk

import asyncio

from bot import Bot

bot = Bot()
loop = asyncio.get_event_loop()

def on_start():
    print("start")
    loop.run_until_complete(bot.start())

def on_stop():
    print("stop")
    loop.run_until_complete(bot.stop())

if __name__ == '__main__':
    root = Tk.Tk()
    frame = Tk.Frame(root)

    start_button = Tk.Button(frame.master, text="start", command = on_start)
    start_button.pack()

    stop_button = Tk.Button(frame.master, text="stop", command = on_stop)
    stop_button.pack()

    root.mainloop()

因此,当按下开始按钮时,机器人会自行启动并连接到 Twitch。但是,GUI 在loop.run_until_complete(bot.start()) 之后卡在on_start() 之后,它永远不会返回。如何在 GUI 上同时运行机器人?

【问题讨论】:

    标签: python tkinter python-asyncio


    【解决方案1】:

    您可以尝试在不同的线程中运行事件循环,并以线程安全的方式向它提交任务。例如:

    loop = asyncio.get_event_loop()
    threading.Thread(daemon=True, target=loop.run_forever).start()
    
    # ... in the GUI:
    
    def on_start():
        print("start")
        asyncio.run_coroutine_threadsafe(loop, bot.start())
    
    def on_stop():
        print("stop")
        asyncio.run_coroutine_threadsafe(loop, bot.stop())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-05
      • 2019-05-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-04-19
      相关资源
      最近更新 更多