@@ -58,11 +58,15 @@ def __init__(self, parent=None):
5858
5959 # 创建顶部信息区域
6060 self .setup_header_info ()
61+ # 创建下载布局
62+ self .setup_download_layout ()
6163 # 创建更新设置区域
6264 self .setup_update_settings ()
65+
6366 # 添加到主界面
6467 self .main_layout .addWidget (self .titleLabel )
6568 self .main_layout .addLayout (self .header_layout )
69+ self .main_layout .addLayout (self .download_layout )
6670 self .main_layout .addWidget (self .update_settings_card )
6771 # 设置窗口布局
6872 self .setLayout (self .main_layout )
@@ -131,11 +135,23 @@ def setup_header_info(self):
131135 button_ring_layout .addWidget (self .indeterminate_ring )
132136 button_ring_layout .addStretch () # 右侧添加拉伸,确保按钮和进度环靠左
133137
138+ # 添加控件到状态布局
139+ status_layout .addWidget (self .status_label )
140+ status_layout .addWidget (self .version_label )
141+ status_layout .addWidget (self .last_check_label )
142+ status_layout .addLayout (button_ring_layout )
143+
144+ # 添加状态布局、取消布局和拉伸到头部布局
145+ self .header_layout .addLayout (status_layout )
146+ self .header_layout .addStretch (1 ) # 添加拉伸因子,将内容向左推
147+
148+ def setup_download_layout (self ):
149+ """设置下载布局"""
134150 # 创建下载信息布局(垂直布局,用于进度条和相关信息)
135- download_layout = QVBoxLayout ()
136- download_layout .setSpacing (5 )
137- download_layout .setAlignment (Qt .AlignLeft )
138- download_layout .setContentsMargins (0 , 0 , 0 , 0 ) # 移除边距
151+ self . download_layout = QVBoxLayout ()
152+ self . download_layout .setSpacing (5 )
153+ self . download_layout .setAlignment (Qt .AlignLeft )
154+ self . download_layout .setContentsMargins (0 , 0 , 0 , 0 ) # 移除边距
139155
140156 # 创建下载进度条(单独一个布局,让它可以延伸到窗口最右端)
141157 self .download_progress = ProgressBar ()
@@ -155,37 +171,17 @@ def setup_header_info(self):
155171 self .cancel_update_button .clicked .connect (self .cancel_update )
156172 self .cancel_update_button .setVisible (False ) # 默认隐藏
157173
158- # 创建取消按钮布局
174+ # 取消按钮布局(与进度条对齐)
159175 cancel_layout = QHBoxLayout ()
160176 cancel_layout .setSpacing (10 )
161177 cancel_layout .setAlignment (Qt .AlignLeft )
162178 cancel_layout .addWidget (self .cancel_update_button )
163179 cancel_layout .addStretch () # 右侧添加拉伸
164180
165181 # 添加控件到下载布局
166- download_layout .addWidget (self .download_progress )
167- download_layout .addWidget (self .download_info_label )
168- download_layout .addLayout (cancel_layout )
169-
170- # 添加控件到状态布局
171- status_layout .addWidget (self .status_label )
172- status_layout .addWidget (self .version_label )
173- status_layout .addWidget (self .last_check_label )
174- status_layout .addLayout (button_ring_layout )
175-
176- # 添加状态布局和下载布局到头部布局
177- self .header_layout .addLayout (status_layout )
178- self .header_layout .addStretch (1 ) # 添加拉伸因子,将内容向左推
179-
180- # 创建单独的进度条布局,让它可以延伸到窗口最右端
181- self .progress_layout = QVBoxLayout ()
182- self .progress_layout .setSpacing (5 )
183- self .progress_layout .setAlignment (Qt .AlignLeft )
184- self .progress_layout .setContentsMargins (0 , 0 , 0 , 0 ) # 移除边距
185- self .progress_layout .addLayout (download_layout )
186-
187- # 添加进度条布局到主布局
188- self .main_layout .insertLayout (2 , self .progress_layout )
182+ self .download_layout .addWidget (self .download_progress )
183+ self .download_layout .addWidget (self .download_info_label )
184+ self .download_layout .addLayout (cancel_layout )
189185
190186 def setup_update_settings (self ):
191187 """设置更新设置区域"""
@@ -340,18 +336,17 @@ def download_and_install(self):
340336 # 获取最新版本信息
341337 latest_version_info = get_latest_version ()
342338 if not latest_version_info :
343- msg_box = MessageBox (
344- get_content_name ("update" , "download_failed" ),
345- get_content_name ("update" , "failed_to_get_version_info" ),
346- self ,
339+ self .status_label .setText (
340+ get_content_name_async ("update" , "failed_to_get_version_info" )
347341 )
348- msg_box .exec ()
349342 return
350343
351344 latest_version = latest_version_info ["version" ]
352345
353346 # 更新状态显示
354- self .status_label .setText (get_content_name ("update" , "downloading_update" ))
347+ self .status_label .setText (
348+ get_content_name_async ("update" , "downloading_update" )
349+ )
355350 self .download_progress .setVisible (True )
356351 self .download_info_label .setVisible (True )
357352 self .cancel_update_button .setVisible (True )
@@ -360,8 +355,9 @@ def download_and_install(self):
360355
361356 # 下载状态变量
362357 self ._download_cancelled = False
363- self ._last_downloaded = 0
364358 self ._start_time = QDateTime .currentDateTime ().toMSecsSinceEpoch ()
359+ self ._last_speed_update = 0
360+ self ._speed_update_interval = 300 # 每300ms更新一次速度
365361
366362 # 定义进度回调函数
367363 def progress_callback (downloaded : int , total : int ):
@@ -378,28 +374,33 @@ def progress_callback(downloaded: int, total: int):
378374 Q_ARG (int , progress ),
379375 )
380376
381- # 计算下载速度
377+ # 格式化速度和总大小
378+ def format_size (size_bytes ):
379+ """格式化文件大小"""
380+ if size_bytes < 1024 :
381+ return f"{ size_bytes } B"
382+ elif size_bytes < 1024 * 1024 :
383+ return f"{ size_bytes / 1024 :.1f} KB"
384+ else :
385+ return f"{ size_bytes / (1024 * 1024 ):.1f} MB"
386+
382387 current_time = QDateTime .currentDateTime ().toMSecsSinceEpoch ()
383- elapsed = current_time - self ._start_time
384- if elapsed > 0 :
385- # 计算下载速度(字节/秒)
386- speed = (downloaded - self ._last_downloaded ) * 1000 / elapsed
387- self ._last_downloaded = downloaded
388- self ._start_time = current_time
389-
390- # 格式化速度和总大小
391- def format_size (size_bytes ):
392- """格式化文件大小"""
393- if size_bytes < 1024 :
394- return f"{ size_bytes } B"
395- elif size_bytes < 1024 * 1024 :
396- return f"{ size_bytes / 1024 :.1f} KB"
397- else :
398- return f"{ size_bytes / (1024 * 1024 ):.1f} MB"
399-
400- speed_str = format_size (speed )
401- total_str = format_size (total )
402- downloaded_str = format_size (downloaded )
388+ total_str = format_size (total )
389+ downloaded_str = format_size (downloaded )
390+
391+ # 每300ms更新一次速度
392+ if (
393+ current_time - self ._last_speed_update
394+ >= self ._speed_update_interval
395+ ):
396+ elapsed = current_time - self ._start_time
397+ if elapsed > 0 :
398+ # 计算累计平均速度(字节/秒)
399+ # 从开始下载到当前的总字节数除以总时间
400+ speed = downloaded * 1000 / elapsed
401+ speed_str = format_size (speed )
402+ else :
403+ speed_str = "0 B/s"
403404
404405 # 更新下载信息标签
405406 info_text = f"{ speed_str } /s | { downloaded_str } / { total_str } "
@@ -410,6 +411,9 @@ def format_size(size_bytes):
410411 Q_ARG (str , info_text ),
411412 )
412413
414+ # 更新上次速度更新时间
415+ self ._last_speed_update = current_time
416+
413417 # 定义下载完成后的处理函数
414418 def on_download_complete (file_path : Optional [str ]):
415419 if self ._download_cancelled :
@@ -418,15 +422,15 @@ def on_download_complete(file_path: Optional[str]):
418422 self .status_label ,
419423 "setText" ,
420424 Qt .QueuedConnection ,
421- Q_ARG (str , get_content_name ("update" , "update_cancelled" )),
425+ Q_ARG (str , get_content_name_async ("update" , "update_cancelled" )),
422426 )
423427 elif file_path :
424428 # 下载成功,开始安装
425429 QMetaObject .invokeMethod (
426430 self .status_label ,
427431 "setText" ,
428432 Qt .QueuedConnection ,
429- Q_ARG (str , get_content_name ("update" , "installing_update" )),
433+ Q_ARG (str , get_content_name_async ("update" , "installing_update" )),
430434 )
431435
432436 # 安装更新
@@ -441,63 +445,41 @@ def on_download_complete(file_path: Optional[str]):
441445 Qt .QueuedConnection ,
442446 Q_ARG (
443447 str ,
444- get_content_name (
448+ get_content_name_async (
445449 "update" , "update_installed_successfully"
446450 ),
447451 ),
448452 )
449- # 显示安装成功消息
450- msg_box = MessageBox (
451- get_content_name ("update" , "update_installed" ),
452- get_content_name ("update" , "update_installed_successfully" ),
453- self ,
454- )
455- msg_box .exec ()
456453 else :
457454 # 安装失败
458455 QMetaObject .invokeMethod (
459456 self .status_label ,
460457 "setText" ,
461458 Qt .QueuedConnection ,
462- Q_ARG (str , get_content_name ("update" , "install_failed" )),
463- )
464- # 显示安装失败消息
465- msg_box = MessageBox (
466- get_content_name ("update" , "install_failed" ),
467- get_content_name ("update" , "failed_to_install_update" ),
468- self ,
459+ Q_ARG (
460+ str , get_content_name_async ("update" , "install_failed" )
461+ ),
469462 )
470- msg_box .exec ()
471463 except Exception as e :
472464 # 安装过程中发生错误
465+ error_text = f"{ get_content_name_async ('update' , 'install_failed' )} : { str (e )} "
473466 QMetaObject .invokeMethod (
474467 self .status_label ,
475468 "setText" ,
476469 Qt .QueuedConnection ,
477- Q_ARG (str , get_content_name ("update" , "install_failed" )),
478- )
479- # 显示安装失败消息
480- msg_box = MessageBox (
481- get_content_name ("update" , "install_failed" ),
482- f"{ get_content_name ('update' , 'failed_to_install_update' )} : { str (e )} " ,
483- self ,
470+ Q_ARG (str , error_text ),
484471 )
485- msg_box .exec ()
486472 else :
487473 # 下载失败
488474 QMetaObject .invokeMethod (
489475 self .status_label ,
490476 "setText" ,
491477 Qt .QueuedConnection ,
492- Q_ARG (str , get_content_name ("update" , "download_failed" )),
493- )
494- # 显示下载失败消息
495- msg_box = MessageBox (
496- get_content_name ("update" , "download_failed" ),
497- get_content_name ("update" , "failed_to_download_update" ),
498- self ,
478+ Q_ARG (
479+ str ,
480+ get_content_name_async ("update" , "failed_to_download_update" ),
481+ ),
499482 )
500- msg_box .exec ()
501483
502484 # 恢复UI状态
503485 QMetaObject .invokeMethod (
@@ -531,10 +513,7 @@ def on_download_complete(file_path: Optional[str]):
531513 Q_ARG (bool , True ),
532514 )
533515 QMetaObject .invokeMethod (
534- self .download_info_label ,
535- "setText" ,
536- Qt .QueuedConnection ,
537- Q_ARG (str , "" ),
516+ self .download_info_label , "setText" , Qt .QueuedConnection , Q_ARG (str , "" )
538517 )
539518
540519 # 定义下载任务类
@@ -561,8 +540,18 @@ def run(self):
561540 def cancel_update (self ):
562541 """取消更新"""
563542 self ._download_cancelled = True
564- self .status_label .setText (get_content_name ("update" , "cancelling_update" ))
565- self .cancel_update_button .setEnabled (False )
543+ QMetaObject .invokeMethod (
544+ self .status_label ,
545+ "setText" ,
546+ Qt .QueuedConnection ,
547+ Q_ARG (str , get_content_name_async ("update" , "cancelling_update" )),
548+ )
549+ QMetaObject .invokeMethod (
550+ self .cancel_update_button ,
551+ "setEnabled" ,
552+ Qt .QueuedConnection ,
553+ Q_ARG (bool , False ),
554+ )
566555
567556 @Slot (str )
568557 def _update_check_status (self , status_text ):
0 commit comments