Python GTK UI在等待函数时冻结

Python GTK UI在等待函数时冻结,python,linux,asynchronous,gtk,python-asyncio,Python,Linux,Asynchronous,Gtk,Python Asyncio,我是Python的初学者,我想用GTK3和Python 3.8制作一个自动更新游戏的应用程序,下载文件,然后安装 我用一个方法创建了一个类,该方法自动获取最新版本,为运行Python的OS选择正确的文件,然后在另一个方法上下载。这是一节课: 导入请求 导入平台 导入异步 类发布管理器: def uuu init uuuu(自我、包名、作者名): self.package\u name=包名称 self.author\u name=作者名称 self.selected_url=“” self.se

我是Python的初学者,我想用GTK3和Python 3.8制作一个自动更新游戏的应用程序,下载文件,然后安装

我用一个方法创建了一个类,该方法自动获取最新版本,为运行Python的OS选择正确的文件,然后在另一个方法上下载。这是一节课:

导入请求
导入平台
导入异步
类发布管理器:
def uuu init uuuu(自我、包名、作者名):
self.package\u name=包名称
self.author\u name=作者名称
self.selected_url=“”
self.selected_filename=“”
异步定义获取资源下载url和名称(self):
url=f“https://api.github.com/repos/{self.author\u name}/{self.package\u name}/releases/latest“
response=requests.get(
网址,
headers={“用户代理”:“OpenRCT2静默启动器”}
)
json_response=response.json()
资产=json_响应[“资产”]
对于存档资产:
如果文件[“内容类型”]=“应用程序/x-ms-dos-executable”:
# ...
#将正确的URL和文件名输出到
#“选定url”和“选定文件名”变量
异步def下载最新资源(自身、下载路径、进度条):
如果self.selected_url==“”:
等待self.get_asset_下载_url_和_name()
response=requests.get(
自行选择的url,
headers={“用户代理”:“OpenRCT2静默启动器”,“接受”:“应用程序/八位字节流”},
流=真
)
response_size=int(response.headers['content-length'])
如果response.status_code==200:
将open(os.path.join(下载\u路径,self.selected\u文件名),“wb”)作为文件:
字节\u读取=0
打印(“下载…”)
对于响应中的块。iter_内容(512):
file.write(块)
字节\u读取+=512
进度=字节\u读取/响应\u大小
#进度条。设置分数(进度)
#^这就是我想要更新进度条的方式,
#我对此进行了评论,以确保这不是问题的根源。
打印(“已成功完成下载”)
这是我执行的
main.py
文件:

导入异步IO
导入asyncio_glib
导入gi
从github导入发布
gi.要求_版本(“Gtk”、“3.0”)
从gi.repository导入Gtk
asyncio.set\u event\u loop\u策略(asyncio\u glib.GLibEventLoopPolicy())
builder=Gtk.builder()
从文件(“layouts/mainWindow.glade”)中添加
def呼叫下载(按钮):
loop=asyncio.get\u event\u loop()
循环。运行\u直到完成(下载\u openrct2())
异步def下载\u openrct2():
manager=releases.ReleaseManager(“OpenRCT2”、“OpenRCT2”)
等待管理员下载最新的资产(“/home/samuel/Downloads/OpenRCT2/”,builder.get对象(“PgrDownload”))
处理程序={
“onDestroy”:Gtk.main_退出,
“onDownloadClick”:呼叫下载
}
生成器。连接信号(处理程序)
win=builder.get_对象(“主窗口”)
赢,全力以赴
Gtk.main()
此代码按预期工作。文件已正确下载,不会返回任何错误。但是,当我按下“下载OpenRCT2”按钮时,GUI就会冻结。您可以看到,我尝试使用基于StackOverflow的
asyncio
asyncio\u glib
解决这个问题,因为
asyncio\u glib
的唯一文档()是在
asyncio.get\u loop\u事件()之前插入
asyncio.set\u event\u loop\u policy(asyncio\u glib.GLibEventLoopPolicy())
我认为这是我唯一需要做的事情

但这并没有解决问题,UI仍然冻结,直到
download\u latest\u asset
方法的最后一行执行完毕,同时不会抛出任何错误。如何使下载方法在下载文件时不冻结UI


提前感谢。

我不熟悉asyncio,但我想知道线程是否对您更合适。线程对我来说在I/O绑定的应用程序中工作得很好。注意,尽管Gtk不是线程安全的。有很多这样的例子。@gtknard我忘了更新这篇文章,最后我用线程和PyPubSub事件来更新UI。然后,我现在完全放弃了UI(决定不需要它),但这个解决方案效果很好。我想稍后我会详细回答我的问题。