-
Notifications
You must be signed in to change notification settings - Fork 555
fix: prevent crash when force-closing during PDF download (#59) #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -699,11 +699,18 @@ class resource_helper: # 获取网站上资源的数据 | |||||||||
|
|
||||||||||
| def thread_it(func, args: tuple = ()) -> None: # 打包函数到线程 | ||||||||||
| t = threading.Thread(target=func, args=args) | ||||||||||
| # t.daemon = True | ||||||||||
| t.daemon = True | ||||||||||
| t.start() | ||||||||||
|
|
||||||||||
| def ui_call(func, *args, **kwargs) -> None: # 在主线程执行 Tkinter UI 更新 | ||||||||||
| root.after(0, lambda: func(*args, **kwargs)) | ||||||||||
| if app_closing: | ||||||||||
| return | ||||||||||
|
|
||||||||||
| try: | ||||||||||
| root.after(0, lambda: (not app_closing) and func(*args, **kwargs)) | ||||||||||
| except Exception: | ||||||||||
| # 主窗口销毁后,root.after 会抛错,直接忽略即可 | ||||||||||
| pass | ||||||||||
|
Comment on lines
+711
to
+713
|
||||||||||
|
|
||||||||||
| def pick_ui_font_family() -> str: # 选择一个合适的字体 | ||||||||||
| try: | ||||||||||
|
|
@@ -722,6 +729,7 @@ def pick_ui_font_family() -> str: # 选择一个合适的字体 | |||||||||
|
|
||||||||||
| session = requests.Session() # 初始化请求 | ||||||||||
| download_states = [] # 初始化下载状态 | ||||||||||
| app_closing = False | ||||||||||
|
||||||||||
| access_token = None | ||||||||||
| headers = { "X-ND-AUTH": 'MAC id="0",nonce="0",mac="0"' } # 设置请求头部,包含认证信息,其中 “MAC id” 即为 Access Token,“nonce” 和 “mac” 不可缺省但可为任意非空值 | ||||||||||
| session.proxies = {} # 全局忽略代理 | ||||||||||
|
|
@@ -778,10 +786,17 @@ def set_icon() -> None: # 设置窗口图标 | |||||||||
| set_icon() # 设置窗口图标 | ||||||||||
|
|
||||||||||
| def on_closing() -> None: # 处理窗口关闭事件 | ||||||||||
| global app_closing | ||||||||||
|
|
||||||||||
| if app_closing: | ||||||||||
| return | ||||||||||
|
|
||||||||||
| if not all(state["finished"] for state in download_states): # 当正在下载时,询问用户 | ||||||||||
| if not messagebox.askokcancel("提示", "下载任务未完成,是否退出?"): | ||||||||||
| return | ||||||||||
|
|
||||||||||
| app_closing = True | ||||||||||
|
|
||||||||||
| current_process = psutil.Process(os.getpid()) # 获取自身的进程 ID | ||||||||||
| child_processes = current_process.children(recursive=True) # 获取自身的所有子进程 | ||||||||||
|
|
||||||||||
|
|
@@ -791,8 +806,10 @@ def on_closing() -> None: # 处理窗口关闭事件 | |||||||||
| except Exception: # 进程可能已经结束 | ||||||||||
| pass | ||||||||||
|
|
||||||||||
| # 结束自身进程 | ||||||||||
| sys.exit(0) | ||||||||||
| try: | ||||||||||
| root.destroy() | ||||||||||
| except Exception: | ||||||||||
| pass | ||||||||||
|
Comment on lines
+811
to
+812
|
||||||||||
| except Exception: | |
| pass | |
| except Exception as e: | |
| print_error(e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lambda function uses
(not app_closing) and func(*args, **kwargs)which will return the result offunc(*args, **kwargs)when app_closing is False, but will return False when app_closing is True. This is correct for preventing execution, but the lambda will still be queued even if app_closing becomes True between line 706 and line 710. Additionally, this creates a redundant check since line 706-707 already guards against app_closing. Consider simplifying toroot.after(0, lambda: func(*args, **kwargs))since the early return on line 706-707 already handles the app_closing check.