Python 使用asyncio并在tkinter窗口之间切换会导致运行时错误

Python 使用asyncio并在tkinter窗口之间切换会导致运行时错误,python,tkinter,python-asyncio,Python,Tkinter,Python Asyncio,我刚开始使用asyncio,以便在执行阻塞任务(如查询数据库)时,尝试使tkinter更具响应性 我遇到的问题是,在Tk的不同实例之间切换时,我从asyncio中得到以下错误:RuntimeError:asyncio.run()不能从运行的事件循环调用 由于粘贴原始代码没有太多意义,我将其缩减为打开和关闭窗口的函数和异步函数 import tkinter as tk from tkinter import Button import asyncio async def two(): a

我刚开始使用asyncio,以便在执行阻塞任务(如查询数据库)时,尝试使tkinter更具响应性

我遇到的问题是,在Tk的不同实例之间切换时,我从asyncio中得到以下错误:
RuntimeError:asyncio.run()不能从运行的事件循环调用

由于粘贴原始代码没有太多意义,我将其缩减为打开和关闭窗口的函数和异步函数

import tkinter as tk
from tkinter import Button
import asyncio

async def two():
    await asyncio.sleep(1)
    await one()
    master.destroy()
    window()

async def one():
    await asyncio.sleep(1)

async def main():
    await asyncio.gather(one(),two())

if __name__ == "__main__":
    def trigger():
        asyncio.run(main())

    def first():
        global master
        try:
            master2.destroy()
        except Exception:
            pass
        master=tk.Tk()
        Button(master, text="Test",command=trigger).pack()
        master.mainloop()

    def window():
        global master2
        master2=tk.Tk()
        Button(master2,text="Back",command=first).pack()
        master2.mainloop()
    first()

运行上面的代码会抛出上述错误。

出于好奇,为什么您需要不止一次的
Tk
实例?我知道最好的做法是使用Toplevel在根目录上创建窗口,但我觉得这不是适合我的场景的最佳解决方案。我有一个让用户登录的窗口,因此登录窗口将是root用户,登录后我打开一个仪表板窗口并关闭登录。我认为将仪表板窗口设置为登录窗口的顶层并不是最佳选择。这也意味着我永远不能退出登录窗口,因为仪表板将绑定到它,因此需要隐藏它。你不能先创建仪表板根目录并隐藏它,创建顶级登录窗口,并在成功登录后返回仪表板吗?虽然我喜欢你的想法,但这将涉及对代码的大量更改。最好的解决方案可能是只有一个Tk实例,但是与windows相关的所有代码都必须在同一个模块上。出于好奇,为什么您需要不止一个Tk的实例?我知道最好的做法是使用Toplevel在根上创建窗口,但我觉得这不是我的方案的最佳解决方案。我有一个让用户登录的窗口,因此登录窗口将是root用户,登录后我打开一个仪表板窗口并关闭登录。我认为将仪表板窗口设置为登录窗口的顶层并不是最佳选择。这也意味着我永远不能退出登录窗口,因为仪表板将绑定到它,因此需要隐藏它。你不能先创建仪表板根目录并隐藏它,创建顶级登录窗口,并在成功登录后返回仪表板吗?虽然我喜欢你的想法,但这将涉及对代码的大量更改。最好的解决方案可能只有一个Tk实例,但是所有与windows相关的代码都必须在同一个模块上。