现在有一个 python 程序,主线程在跑 flask ,同时运行了若干个子线程,这些子线程中如果有异常,需要做个弹框提示,点击 OK 或 Cancel 决定是否发送错误报告。
本想着直接拿 tkinter 简单弄一下就完事,但这些 GUI 框架似乎都只能在主线程里面跑 mainloop…… 如果另起一个进程来运行对话框,又涉及进程间通信,是不是有点小题大做了?想知道有没有简单点的办法呢?
1
luckyrayyy 2023-10-26 21:24:54 +08:00
进程间通信有啥小题大做的
|
2
geelaw 2023-10-26 21:26:21 +08:00 via iPhone
最简单的方法是在最开始开一个新的线程运行原来主线程的代码。
我不了解 tkinter 和 flask ,如果你告诉我两个都需要在主线程运行,那就必须重新编程。(但我不能理解为什么一个库要令主线程是特殊的。) |
3
yolee599 2023-10-26 21:27:19 +08:00 via Android
正规做法就是用进程间通讯做的啊,mainloop 只跑 gui
|
4
ding2dong 2023-10-26 21:34:28 +08:00
新增一个弹窗脚本,用 subprocess.run()调用该脚本,根据返回值判断是否需要发送错误报告。不知这样可否?
|
5
darcyC 2023-10-26 22:23:10 +08:00
用 4 楼说的方法 或者就是你说的 进程间通讯,tkinter 只能运行在主线程 同时 flask 的部分功能也只能运行在主线程(见 https://stackoverflow.com/questions/31264826/start-a-flask-application-in-separate-thread )我个人推荐你用 4 楼的方法吧
|
6
hefish 2023-10-26 22:36:54 +08:00
楼上的列位大佬,OP 的意思就是不用进程间通信,但还是得把进程间通信的事儿给办了。 大家按照这个思路来。。。
|
7
qbqbqbqb 2023-10-26 23:11:10 +08:00
tkinter 可以在子线程里用 event_generate 产生一个事件,然后主线程挂一个 handler 来处理
|
8
ignor OP 好吧,之前没做过 GUI ,原来弹个框是这么麻烦的事……
想了一下,这个通信过程有点不知道该怎么处理合适?我希望能封装成一个通用的方法,每次需要弹框就调用一下,大佬们有没有好的实践思路? |
9
coolair 2023-10-26 23:27:35 +08:00
用 pyqt 啊,跟前端一样 emit 啊,gui 主线程就能接收到其他线程 emit 来的数据,然后弹窗就可以了啊。
|
10
ignor OP @coolair pyqt 的 gui 主线程也是 python 的主线程吧?这里的问题是主线程已经被 flask 占用了
|
11
neoblackcap 2023-10-26 23:48:14 +08:00 2
@ignor 所有的带 GUI 的程序,主线程都是指 gui mainloop 所在的线程。因为只有它才能绘制图像不出错。
事实上你应该先启动 GUI 主线程,然后再通过 worker 线程来跑 flask 。然后所有跟 GUI 相关的问题都可以归纳回如何跟主线程通信了。 |
12
fgwmlhdkkkw 2023-10-26 23:54:17 +08:00 via Android
有错误存到数据库,然后做 api ,调用浏览器打开。
这页面里使用 websocket 连接,这个服务器可以判断有没有正在浏览的页面。 |
13
duke807 2023-10-27 00:04:45 +08:00 via Android
非主线程里实现一个弹窗式对话框,或者显示单独的窗口,都是很轻松的啊,linux 、windows 都没问题,macos 除外
|
14
ksc010 2023-10-27 00:22:05 +08:00
有个疑问,子进程遇到异常后,还继续执行吗?
|
15
NoOneNoBody 2023-10-27 01:52:39 +08:00
import easygui
... |
16
nuk 2023-10-27 02:57:26 +08:00
简单点就直接 messagebox ,同步调用用不着 mainloop
|
17
vialon17 2023-10-27 08:41:47 +08:00 1
我最近倒是做了一个主 qt+flask 的应用,直接开 qthread 包裹一下 flask 就可以了。
弹窗直接用 qt 模板就行。 |
18
4kingRAS 2023-10-27 10:44:57 +08:00
程序写少了,稍微接触过 JS 就可以很轻松理解这个问题。
所有的 UI 框架(安卓,ios ,win32 ,swing ,qt ,Web ,js ,UE UNITY 等若干)都不支持子线程更新 UI 或者说是做不到 UI 更新线程安全,所有 UI 框架都采用 eventloop 的方式,无数人在这个地方踩过无数坑了。 Sun 的副总裁曾经有个博客讲过这个事: https://zhuanlan.zhihu.com/p/44639688 |
19
ignor OP @4kingRAS js 写了也有上万行了吧,从没想过……但可能正是因为 js 用的事件驱动,所以遇不到这样的问题
|
20
koast 2023-10-27 21:03:17 +08:00
这需求多少看起来感觉有点别扭,C#里解决这个事情的方法倒是有点特别,用委托,给委托注册上处理函数,然后就可以在子线程里以主线程的身份进行函数调用了。python 里的话,感觉还是#4 的方法最简单。
|