@@ -256,6 +256,8 @@ def __init__(self):
256256
257257 # 初始化需要在加载资源前定义的属性
258258 self .eval_images = {} # To store evaluation images
259+ # ========== 新增:字体缓存 ==========
260+ self .font_cache = {}
259261
260262 # 计算动态尺寸
261263 self .calculate_sizes ()
@@ -369,6 +371,38 @@ def load_resources(self):
369371 self .eval_images [name ] = None
370372 print (f"警告: 走法评估图片加载失败: resource/pieces/{ name } .png" )
371373
374+ # ========== 新增:安全获取字体的方法 ==========
375+ def get_font (self , name , size , bold = False ):
376+ """尝试多种方式获取字体,避免SysFont初始化失败"""
377+ key = (name , size , bold )
378+ if key in self .font_cache :
379+ return self .font_cache [key ]
380+
381+ font = None
382+ # 先尝试用SysFont(可能触发异常)
383+ try :
384+ font = pygame .font .SysFont (name , size , bold = bold )
385+ except Exception :
386+ pass
387+
388+ # 如果失败,尝试直接加载simhei.ttf文件(常见路径)
389+ if font is None :
390+ try :
391+ font = pygame .font .Font ("C:/Windows/Fonts/simhei.ttf" , size )
392+ except Exception :
393+ pass
394+
395+ # 最后回退到默认字体
396+ if font is None :
397+ try :
398+ font = pygame .font .Font (None , size )
399+ except Exception as e :
400+ # 极罕见情况:连默认字体都失败,则创建一个最简单的字体(Pygame应能处理)
401+ font = pygame .font .Font (None , size )
402+
403+ self .font_cache [key ] = font
404+ return font
405+
372406 def start_katago (self ):
373407 """启动KataGo进程"""
374408 try :
@@ -813,15 +847,16 @@ def draw_error_dialog(self):
813847 pygame .draw .rect (self .screen , (200 , 200 , 200 ), (dialog_x , dialog_y , dialog_width , dialog_height ))
814848 pygame .draw .rect (self .screen , (100 , 100 , 100 ), (dialog_x , dialog_y , dialog_width , dialog_height ), 2 )
815849
816- font = pygame .font .SysFont (FONT_NAME , 20 )
850+ # 使用 get_font 替代 SysFont
851+ font = self .get_font (FONT_NAME , 20 )
817852 error_text = font .render (self .error_message , True , (0 , 0 , 0 ))
818853 self .screen .blit (error_text , (dialog_x + 20 , dialog_y + 30 ))
819854
820855 button_rect = pygame .Rect (dialog_x + 150 , dialog_y + 90 , 100 , 40 )
821856 pygame .draw .rect (self .screen , (150 , 150 , 150 ), button_rect )
822857 pygame .draw .rect (self .screen , (0 , 0 , 0 ), button_rect , 2 )
823858
824- button_font = pygame . font . SysFont (FONT_NAME , 18 )
859+ button_font = self . get_font (FONT_NAME , 18 ) # 修改
825860 button_text = button_font .render ("确定" , True , (0 , 0 , 0 ))
826861 self .screen .blit (button_text , (button_rect .centerx - 20 , button_rect .centery - 10 ))
827862
@@ -832,7 +867,7 @@ def draw_analysis_panel(self):
832867 pygame .draw .rect (self .screen , (240 , 240 , 240 ),
833868 (panel_x , 0 , self .sidebar_width , panel_height ))
834869
835- font = pygame . font . SysFont (FONT_NAME , 16 )
870+ font = self . get_font (FONT_NAME , 16 ) # 修改
836871 text = font .render ("选点列表" , True , (0 , 0 , 0 ))
837872 self .screen .blit (text , (panel_x + 10 , 10 ))
838873
@@ -851,12 +886,12 @@ def draw_analysis_panel(self):
851886
852887 situation_text , text_color , score_text , score_color = self .get_situation_text ()
853888
854- font = pygame . font . SysFont (FONT_NAME , 32 , bold = False )
889+ font = self . get_font (FONT_NAME , 32 , bold = False ) # 修改
855890 score_surf = font .render (score_text , True , score_color )
856891 score_rect = score_surf .get_rect (center = (panel_x + 50 , situation_y + 40 ))
857892 self .screen .blit (score_surf , score_rect )
858893
859- font = pygame . font . SysFont (FONT_NAME , 24 , bold = True )
894+ font = self . get_font (FONT_NAME , 24 , bold = True ) # 修改
860895 text_surf = font .render (situation_text , True , text_color )
861896 text_rect = text_surf .get_rect (center = (panel_x + self .sidebar_width // 2 , situation_y + 40 ))
862897 self .screen .blit (text_surf , text_rect )
@@ -924,7 +959,7 @@ def draw_information_panel(self):
924959 x0 = self .announce_width + self .board_width
925960 pygame .draw .rect (self .screen , (160 , 160 , 160 ),
926961 (x0 , y0 , self .sidebar_width , 250 ))
927- font = pygame . font . SysFont (FONT_NAME , 18 )
962+ font = self . get_font (FONT_NAME , 18 ) # 修改
928963
929964 mode_color = (0 , 200 , 0 ) if self .simple_mode else (200 , 0 , 0 )
930965 mode_text = "精简模式" if self .simple_mode else "专业模式"
@@ -983,11 +1018,11 @@ def draw_gtp_console(self):
9831018 pygame .draw .rect (self .screen , (255 , 255 , 255 ),
9841019 (console_x , console_top , self .sidebar_width , self .gtp_console_height ))
9851020
986- font = pygame . font . SysFont (FONT_NAME , 20 )
1021+ font = self . get_font (FONT_NAME , 20 ) # 修改
9871022 title = font .render ("GTP 信息" , True , (0 , 0 , 0 ))
9881023 self .screen .blit (title , (console_x + 10 , console_top - 30 ))
9891024
990- font = pygame . font . SysFont (FONT_NAME , GTP_FONT_SIZE )
1025+ font = self . get_font (FONT_NAME , GTP_FONT_SIZE ) # 修改
9911026 y_increase = GTP_FONT_SIZE + 2
9921027 y_start = console_top + 30 - self .scroll_offset * y_increase
9931028 with self .analysis_lock :
@@ -1013,7 +1048,8 @@ def draw_scrollbar(self, top, console_x):
10131048
10141049 def draw_text (self , text , pos , anchor = 'topleft' , color = (0 , 0 , 0 ), bg_color = None , font_size = 20 , bold = False , font_name = FONT_NAME ):
10151050 """改进的文字绘制支持多行和对齐"""
1016- font = pygame .font .SysFont (font_name , int (FONT_SCALE * font_size ), bold = bold )
1051+ # 使用 get_font 替代 SysFont
1052+ font = self .get_font (font_name , int (FONT_SCALE * font_size ), bold = bold )
10171053 lines = text .split ('\n ' )
10181054
10191055 is_w_anchor = anchor == 'w'
0 commit comments