@@ -22,19 +22,48 @@ def __init__(self, parent=None):
2222 self .layout .setContentsMargins (15 , 15 , 15 , 15 )
2323 self .layout .setSpacing (10 )
2424 self .content_widgets = []
25+ self .cached_widgets = []
2526
2627 def update_content (self , widgets ):
27- """更新内容控件"""
28- # 清除现有内容
29- for widget in self .content_widgets :
28+ """更新内容控件(优化版,复用控件避免闪烁)"""
29+ if not widgets :
30+ return
31+
32+ min_count = min (len (widgets ), len (self .cached_widgets ))
33+
34+ for i in range (min_count ):
35+ old_widget = self .cached_widgets [i ]
36+ new_widget = widgets [i ]
37+
38+ if old_widget and new_widget :
39+ old_layout = old_widget .layout ()
40+ new_layout = new_widget .layout ()
41+
42+ if old_layout and new_layout :
43+ for j in range (min (old_layout .count (), new_layout .count ())):
44+ old_item = old_layout .itemAt (j )
45+ new_item = new_layout .itemAt (j )
46+
47+ if old_item and new_item :
48+ old_label = old_item .widget ()
49+ new_label = new_item .widget ()
50+
51+ if old_label and new_label :
52+ old_label .setText (new_label .text ())
53+ old_label .setStyleSheet (new_label .styleSheet ())
54+
55+ for i in range (min_count , len (widgets )):
56+ self .layout .addWidget (widgets [i ])
57+ self .content_widgets .append (widgets [i ])
58+
59+ for i in range (min_count , len (self .cached_widgets )):
60+ widget = self .cached_widgets [i ]
3061 self .layout .removeWidget (widget )
3162 widget .deleteLater ()
32- self .content_widgets .clear ()
63+ if widget in self .content_widgets :
64+ self .content_widgets .remove (widget )
3365
34- # 添加新内容
35- for widget in widgets :
36- self .layout .addWidget (widget )
37- self .content_widgets .append (widget )
66+ self .cached_widgets = widgets
3867
3968 # 确保新添加的 BodyLabel 可见:根据主题强制设置前景色
4069 try :
@@ -45,14 +74,11 @@ def update_content(self, widgets):
4574 fg = "#ffffff" if is_dark_theme (qconfig ) else "#000000"
4675
4776 def apply_fg_to (w ):
48- # 如果是直接的 BodyLabel,设置样式
4977 if isinstance (w , QFBodyLabel ):
5078 existing = w .styleSheet () or ""
5179 if "color:" not in existing :
52- # 保留已有样式,追加颜色
5380 w .setStyleSheet (existing + f" color: { fg } ;" )
5481 else :
55- # 遍历子控件查找 BodyLabel
5682 for child in w .findChildren (QFBodyLabel ):
5783 existing = child .styleSheet () or ""
5884 if "color:" not in existing :
@@ -64,7 +90,6 @@ def apply_fg_to(w):
6490 except Exception as e :
6591 logger .exception ("应用前景色到内容控件时出错: {}" , e )
6692 except Exception :
67- # 忽略主题检测错误,保持原样
6893 pass
6994
7095
@@ -133,6 +158,9 @@ def __init__(self, parent=None):
133158 # 关闭动画
134159 self .hide_animation = None
135160
161+ # 缓存的标签,用于复用
162+ self .cached_student_labels = []
163+
136164 # 启动周期性置顶
137165 self ._start_periodic_topmost ()
138166
@@ -758,7 +786,7 @@ def update_content(
758786 font_settings_group = None ,
759787 settings_group = None ,
760788 ):
761- """更新通知窗口的内容
789+ """更新通知窗口的内容(优化版,复用控件避免闪烁)
762790
763791 Args:
764792 student_labels: 包含学生信息的BodyLabel控件列表
@@ -778,34 +806,59 @@ def update_content(
778806 elif font_settings_group == "lottery_settings" :
779807 self .settings_group = "lottery_notification_settings"
780808
781- # 清除现有内容
782- while self .content_layout .count ():
783- item = self .content_layout .takeAt (0 )
784- widget = item .widget ()
785- if widget :
786- widget .deleteLater ()
787-
788- # 添加新内容
789- if student_labels :
790- for label in student_labels :
791- # 如果有字体设置,则应用到标签上
792- if font_settings_group :
793- # 检查是否使用全局字体
794- use_global_font = readme_settings_async (
795- font_settings_group , "use_global_font"
809+ if not student_labels :
810+ return
811+
812+ min_count = min (len (student_labels ), len (self .cached_student_labels ))
813+
814+ for i in range (min_count ):
815+ old_widget = self .cached_student_labels [i ]
816+ new_widget = student_labels [i ]
817+
818+ if old_widget and new_widget :
819+ old_layout = old_widget .layout ()
820+ new_layout = new_widget .layout ()
821+
822+ if old_layout and new_layout :
823+ for j in range (min (old_layout .count (), new_layout .count ())):
824+ old_item = old_layout .itemAt (j )
825+ new_item = new_layout .itemAt (j )
826+
827+ if old_item and new_item :
828+ old_label = old_item .widget ()
829+ new_label = new_item .widget ()
830+
831+ if old_label and new_label :
832+ old_label .setText (new_label .text ())
833+ old_label .setStyleSheet (new_label .styleSheet ())
834+
835+ for i in range (min_count , len (student_labels )):
836+ label = student_labels [i ]
837+ # 如果有字体设置,则应用到标签上
838+ if font_settings_group :
839+ # 检查是否使用全局字体
840+ use_global_font = readme_settings_async (
841+ font_settings_group , "use_global_font"
842+ )
843+ custom_font = None
844+ if use_global_font == 1 : # 不使用全局字体,使用自定义字体
845+ custom_font = readme_settings_async (
846+ font_settings_group , "custom_font"
796847 )
797- custom_font = None
798- if use_global_font == 1 : # 不使用全局字体,使用自定义字体
799- custom_font = readme_settings_async (
800- font_settings_group , "custom_font"
848+ if custom_font and hasattr (label , "setStyleSheet" ):
849+ # 获取当前样式表并添加字体设置
850+ current_style = label .styleSheet ()
851+ label .setStyleSheet (
852+ f"font-family: '{ custom_font } '; { current_style } "
801853 )
802- if custom_font and hasattr (label , "setStyleSheet" ):
803- # 获取当前样式表并添加字体设置
804- current_style = label .styleSheet ()
805- label .setStyleSheet (
806- f"font-family: '{ custom_font } '; { current_style } "
807- )
808- self .content_layout .addWidget (label )
854+ self .content_layout .addWidget (label )
855+
856+ for i in range (min_count , len (self .cached_student_labels )):
857+ widget = self .cached_student_labels [i ]
858+ self .content_layout .removeWidget (widget )
859+ widget .deleteLater ()
860+
861+ self .cached_student_labels = student_labels
809862
810863 # 确保颜色与当前主题同步
811864 try :
0 commit comments