var_dump展示不全,出现省略号

本文介绍如何通过配置xdebug扩展来优化PHP中var_dump函数的输出结果,使其能够更清晰地展示复杂数组结构。

我们使用php的var_dump函数,可以更直观的查看输出结果,包括类型,数量等详细信息。此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
但是在使用过程中,发现数组深度高,数组数量大等情况会出现省略号,这是什么原因呢。
原来php的var_dump是安装模块xdebug后的函数,这个模块可以配置其显示信息参数:

解决方法:
在php.ini里的xdebug节点中,追加一下配置:

1
2
3
4
5
 
xdebug.var_display_max_children=128
xdebug.var_display_max_data=512    
xdebug.var_display_max_depth=5  
 





上面代表的意思,就如代码命名这么直观:

1
2
3
4
5
 
xdebug.var_display_max_children // 最多孩子节点数
xdebug.var_display_max_data// 最大字节数
xdebug.var_display_max_depth// 最大深度
 





别忘了重启PHP服务..

根据自己显示的信息来配置吧。

强调:上面的代码是能够运行,现在修改,只是局部修改问题,要胡乱修改。。。修改时一定要说明在什么类的什么地方,这样要用户进行修改。找准位置,认真修改,本着用户至上的原则。生成完整代码。。。问题:1.主界面要求分成三栏,这里的设计是正确的,而子类界面咋出现的又是另一个界面,明明要求只有在动态区里是每个模块专用的,其它的区域给主界面是完一样。。。# ==================== 主界面修改 ==================== class MainInterface: def __init__(self, root: Tk, pool: NumberPool): self.root = root self.pool = pool self.left_panel = None self.center_frame = None self.right_panel = None self.core_vars = {} self.pool_vars = {} self.status_var = StringVar() self.dynamic_text = None self.current_module = None self._setup_ui() self._setup_event_handlers() self.module_instances = {} # 添加模块实例存储 self._init_modules() # 初始化所有模块 # 初始化排除号码相关控件 self.exclude_front_entries = [] self.exclude_back_entries = [] self.front_dan_entries = [] self.back_dan_entries = [] # 初始化结果文本控件 self.result_text = None # 初始化排除号码变量 self.exclude_front_var = StringVar() self.exclude_back_var = StringVar() self.recommend_front_var = StringVar() self.recommend_back_var = StringVar() # 初始化模块内容框架 self.dynamic_content = None self.module_content_frame = None self.labels = { 'InputAnalysis_analysis': [ "输入号码:" , "前区:" , "后区:" , "推荐号码:", "前区:" , "后区:", ], 'combination_analysis': [ "前区热号:", "前数字频:", "前频繁推:", "后区热号:", "后数字频:", "后低频推:" ], 'follow_analysis': [ "前推荐多:", "前推荐少:", "后推荐多:", "后推荐少:" ], 'trend_analysis': [ "和值:", "质合比:", "奇偶比:", "断区推荐:", "连号推荐:", "冷热推荐:", "后区热号:", "后区冷号:", "趋势号:" ], 'NumberGeneration_analysis': [ "胆码:" , "前区:" , "后区:", "推荐5注号码:", "1:" "", "2:" "", "3:" "", "4:" "", "5:" "" ], } # 初始化所有模块的条目引用 self.front_dan_entry = None self.back_dan_entry = None self.result_text = None self.exclude_front_entry = None self.exclude_back_entry = None self.front_entry = None self.back_entry = None def _focus_adjacent_entry(self, event, current_idx, offset, area): """移动焦点到相邻的输入框""" entries = self.front_exclude_entries if area == 'front' else self.back_exclude_entries new_idx = current_idx + offset if 0 <= new_idx < len(entries): entries[new_idx].focus_set() def _init_modules(self): """初始化所有分析模块""" modules = { 'input_analysis': InputAnalysisModule, 'combination_analysis': CombinationAnalysisModule, 'follow_analysis': FollowAnalysisModule, 'trend_analysis': TrendAnalysisModule, 'number_generation': NumberGenerationModule } for name, cls in modules.items(): self.module_instances[name] = cls(name) def _setup_event_handlers(self): """初始化事件处理器""" event_center.subscribe(EventType.MODULE_COMPLETE, self._handle_module_complete) event_center.subscribe(EventType.UI_UPDATE, self._handle_ui_update) event_center.subscribe(EventType.EXCLUDE_NUMBERS, self._handle_exclude_numbers) def _setup_ui(self): self.root.title(f"大乐透智能分析平台 - {GlobalConfig.VERSION}") self.root.geometry("1400x800") # 添加主标题(居中显示在最上面) title_frame = Frame(self.root) title_frame.pack(fill='x', pady=5) Label(title_frame, text="大乐透智能分析平台", font=('微软雅黑', 16, 'bold')).pack(expand=True) # 主容器 main_container = Frame(self.root) main_container.pack(fill='both', expand=True, padx=5, pady=(0, 5)) # 左侧面板 self.left_panel = Frame(main_container, width=200, bg="#eaeaea") self.left_panel.pack(side='left', fill='y', padx=(0, 5)) # 中间内容区 self.center_frame = Frame(main_container, width=400) self.center_frame.pack(side='left', fill='both', expand=True) # 右侧面板 self.right_panel = Frame(main_container, width=700, bg="#f5f5f5") self.right_panel.pack(side='right', fill='y') # 初始化各区域 self._setup_left_panel() self._setup_center_area() self._setup_right_panel() def _setup_left_panel(self): """初始化左侧模块按钮区""" module_names = { 'input_analysis': '1. 输入分析', 'combination_analysis': '2. 组合分析', 'follow_analysis': '3. 跟随分析', 'trend_analysis': '4. 趋势分析', 'number_generation': '5. 数字生成' } for module in GlobalConfig.MODULES: Button( self.left_panel, text=module_names[module], width=18, command=lambda m=module: self._on_module_button_click(m) ).pack(pady=3, padx=5, ipady=3) def _setup_center_area(self): """设置中间区域布局""" # 期号区 period_frame = Frame(self.center_frame, height=30, bd=1, relief='solid') period_frame.pack(fill='x', pady=(0, 5)) Label(period_frame, text="期号: ", font=('微软雅黑', 10)).pack(side='left') self.period_var = StringVar(value="2023001") Label(period_frame, textvariable=self.period_var, font=('微软雅黑', 10, 'bold')).pack(side='left') # 核心区 core_frame = Frame(self.center_frame, bd=1, relief='solid') core_frame.pack(fill='both', expand=True, pady=(0, 5)) # 核心区标题 Label(core_frame, text="核心区", font=('微软雅黑', 12, 'bold')).pack(anchor='w', padx=5, pady=2) # 核心数据展示 self.core_vars = { 'front_area': StringVar(), 'back_area': StringVar(), 'front_hot': StringVar(), 'front_cold': StringVar(), 'back_hot': StringVar(), 'back_cold': StringVar() } for label, var_name in [ ("前区:", 'front_area'), ("后区:", 'back_area'), ("前区热号:", 'front_hot'), ("前区冷号:", 'front_cold'), ("后区热号:", 'back_hot'), ("后区冷号:", 'back_cold') ]: frame = Frame(core_frame) frame.pack(fill='x', padx=5, pady=2) Label(frame, text=label, width=10, anchor='w').pack(side='left') # 添加容器Frame实现右边距2px entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True, padx=(0, 2)) entry = Entry(entry_container, textvariable=self.core_vars[var_name], font=('微软雅黑', 10), state='readonly', readonlybackground='#f0f0f0', relief='sunken', bd=1) entry.pack(fill='x', expand=True) # 动态区 dynamic_frame = Frame(self.center_frame, bd=1, relief='solid') dynamic_frame.pack(fill='both', expand=True) # 动态区标题框架 dynamic_header = Frame(dynamic_frame) dynamic_header.pack(fill='x', padx=5, pady=5) Label(dynamic_header, text="动态区", font=('微软雅黑', 12, 'bold')).pack(side='left') # 按钮框架(靠右) btn_frame = Frame(dynamic_header) btn_frame.pack(side='right') Button(btn_frame, text="运行", width=8, command=self._run_current_module).pack(side='left', padx=2) Button(btn_frame, text="清除", width=8, command=self._clear_dynamic_content).pack(side='left', padx=2) Button(btn_frame, text="保存", width=8, command=self._save_dynamic_content).pack(side='left', padx=2) Button(btn_frame, text="刷新", width=8, command=self._refresh_dynamic).pack(side='left', padx=2) # 模块内容容器 self.module_content_frame = Frame(dynamic_frame) self.module_content_frame.pack(fill='both', expand=True, padx=5, pady=5) def _run_current_module(self): """运行当前模块""" if self.current_module: self._run_module(self.current_module) def _clear_dynamic_content(self): """清除动态区内容""" if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') def _save_dynamic_content(self): """保存动态区内容""" if hasattr(self, 'result_text') and self.result_text: content = self.result_text.get(1.0, 'end') with open('dynamic_content.txt', 'w', encoding='utf-8') as f: f.write(content) messagebox.showinfo("保存成功", "动态区内容已保存") def _refresh_dynamic(self): """刷新动态区""" if self.current_module: self._on_module_button_click(self.current_module) def _setup_right_panel(self): """设置右侧号码池布局""" # 号码池标题 pool_title_frame = Frame(self.right_panel) pool_title_frame.pack(fill='x', pady=5) Label(pool_title_frame, text="号码池", font=('微软雅黑', 12, 'bold')).pack(anchor='w') # 号码池内容区(添加边框和2px内边距) pool_content = Frame(self.right_panel, bd=1, relief='solid', padx=2, pady=2) pool_content.pack(fill='both', expand=True, padx=5, pady=5) # 创建Canvas和Scrollbar canvas = Canvas(pool_content, highlightthickness=0) scrollbar = Scrollbar(pool_content, orient="vertical", command=canvas.yview) scrollable_frame = Frame(canvas) scrollable_frame.bind( "<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")) ) canvas.create_window((0, 0), window=scrollable_frame, anchor="nw") canvas.configure(yscrollcommand=scrollbar.set) # 号码池项目 - 优化布局和样式(带2px右边距) for label, var_name, row_id in GlobalConfig.UI_CONFIG: frame = Frame(scrollable_frame) frame.grid(row=row_id, column=0, sticky='ew', padx=0, pady=1) # 移除水平padding # 左侧标签(固定宽度8字符) lbl = Label(frame, text=label, width=8, anchor='w') lbl.pack(side='left', padx=(0, 5)) # 标签右侧留5px间距 # 右侧输入框容器(带2px右边距) entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True, padx=(0, 2)) var = StringVar() self.pool_vars[var_name] = var entry = Entry(entry_container, textvariable=var, font=('微软雅黑', 9), state='readonly', readonlybackground='#f0f0f0', relief='sunken', bd=1) entry.pack(fill='x', expand=True) canvas.pack(side="left", fill="both", expand=True) scrollbar.pack(side="right", fill="y") # 底部按钮区 btn_frame = Frame(self.right_panel) btn_frame.pack(fill='x', pady=5) Button(btn_frame, text="整理", width=10, command=self._organize_data).pack(side='left', padx=5) Button(btn_frame, text="冻结", width=10, command=self._freeze_data).pack(side='left', padx=5) Button(btn_frame, text="导出", width=10).pack(side='left', padx=5) def _organize_data(self): """整理号码池数据""" organize_event = Event( event_id=int(time.time()), type=EventType.DATA_ORGANIZE, source='main_ui', target='pool' ) event_center.publish(organize_event) def _freeze_data(self): """冻结号码池数据""" freeze_event = Event( event_id=int(time.time()), type=EventType.DATA_FREEZE, source='main_ui', target='pool' ) event_center.publish(freeze_event) def _on_module_button_click(self, module: str): """完重构的模块显示方法 - 嵌入主界面动态区""" self.status_var.set(f"打开 {module} 模块...") self.current_module = module # 清除之前的动态内容 if self.dynamic_content: self.dynamic_content.destroy() # 创建模块专属容器 self.dynamic_content = Frame(self.module_content_frame) self.dynamic_content.pack(fill='both', expand=True, padx=5, pady=5) # 顶部模块标签区 top_label_frame = Frame(self.dynamic_content) top_label_frame.pack(fill='x', pady=5) module_labels = { 'input_analysis': '1. 输入分析', 'combination_analysis': '2. 组合分析', 'follow_analysis': '3. 跟随分析', 'trend_analysis': '4. 趋势分析', 'number_generation': '5. 数字生成' } Label(top_label_frame, text=module_labels.get(module, module), font=('微软雅黑', 14, 'bold')).pack() # 内容区容器 content_frame = Frame(self.dynamic_content, bd=1, relief='solid') content_frame.pack(fill='both', expand=True, padx=5, pady=5) # 根据模块类型创建特定内容 if module == "input_analysis": self._create_input_analysis_content(content_frame) elif module == "combination_analysis": self._create_combination_analysis_content(content_frame) elif module == "follow_analysis": self._create_follow_analysis_content(content_frame) elif module == "trend_analysis": self._create_trend_analysis_content(content_frame) elif module == "number_generation": self._create_number_generation_content(content_frame) # 底部按钮区 bottom_frame = Frame(self.dynamic_content) bottom_frame.pack(pady=5, fill='x') Button(bottom_frame, text="运行", command=lambda: self._run_module(module)).pack(side='left', padx=5) Button(bottom_frame, text="清除", command=lambda: self._clear_module_data(module)).pack(side='left', padx=5) Button(bottom_frame, text="保存", command=lambda: self._save_module_data(module)).pack(side='left', padx=5) Button(bottom_frame, text="刷新", command=lambda: self._on_module_renovate(module)).pack(side='right', padx=5) def _create_ui_element(self, parent, label_text): """创建统一的UI元素(带右边距2px)""" frame = Frame(parent) frame.pack(fill='x', pady=2) # 标签固定宽度 Label(frame, text=label_text, width=12, anchor='w').pack(side='left') # 添加容器Frame实现右边距2px entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True, padx=(0, 2)) return entry_container def _create_input_analysis_content(self, parent: Frame): """创建输入分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) # 排除号码区 exclude_frame = Frame(content_frame) exclude_frame.pack(fill='x', pady=5) # 排除号码标签 Label(exclude_frame, text="排除号码:", font=('微软雅黑', 10, 'bold')).pack(anchor='w', pady=5) # 前区排除号码 front_exclude_frame = Frame(exclude_frame) front_exclude_frame.pack(fill='x', pady=2) Label(front_exclude_frame, text="前区:", width=5, anchor='w').pack(side='left') self.exclude_front_entry = Entry(front_exclude_frame) self.exclude_front_entry.pack(side='left', fill='x', expand=True) # 后区排除号码 back_exclude_frame = Frame(exclude_frame) back_exclude_frame.pack(fill='x', pady=2) Label(back_exclude_frame, text="后区:", width=5, anchor='w').pack(side='left') self.exclude_back_entry = Entry(back_exclude_frame) self.exclude_back_entry.pack(side='left', fill='x', expand=True) # 号码输入区 input_frame = Frame(content_frame) input_frame.pack(fill='x', pady=5) Label(input_frame, text="输入号码:", font=('微软雅黑', 10, 'bold')).pack(anchor='w', pady=5) # 前区号码 front_frame = Frame(input_frame) front_frame.pack(fill='x', pady=2) Label(front_frame, text="前区:", width=5, anchor='w').pack(side='left') self.front_entry = Entry(front_frame) self.front_entry.pack(side='left', fill='x', expand=True) # 后区号码 back_frame = Frame(input_frame) back_frame.pack(fill='x', pady=2) Label(back_frame, text="后区:", width=5, anchor='w').pack(side='left') self.back_entry = Entry(back_frame) self.back_entry.pack(side='left', fill='x', expand=True) # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True, pady=5) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_combination_analysis_content(self, parent: Frame): """创建组合分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) # 使用预定义的labels for label in self.labels['combination_analysis']: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=label, width=12, anchor='w', font=('微软雅黑', 10, 'bold')).pack(side='left') entry = Entry(frame, width=30, state='readonly', readonlybackground='#f0f0f0') entry.pack(side='left', padx=5) # 保存对控件的引用 var_name = label.replace(':', '').replace(' ', '_') setattr(self, f"{var_name}_entry", entry) # 直接保存到实例变量 if var_name == "front_hot": self.front_hot_entry = entry elif var_name == "front_freq": self.front_freq_entry = entry elif var_name == "front_freq_rec": self.front_freq_rec_entry = entry elif var_name == "back_hot": self.back_hot_entry = entry elif var_name == "back_freq": self.back_freq_entry = entry elif var_name == "back_infreq_rec": self.back_infreq_rec_entry = entry # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_follow_analysis_content(self, parent: Frame): """创建跟随分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) for label in self.labels['follow_analysis']: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=label, width=12, anchor='w', font=('微软雅黑', 10, 'bold')).pack(side='left') entry = Entry(frame, width=30, state='readonly', readonlybackground='#f0f0f0') entry.pack(side='left', padx=5) var_name = label.replace(':', '').replace(' ', '_') setattr(self, f"{var_name}_entry", entry) # 直接保存到实例变量 if var_name == "front_more": self.front_more_entry = entry elif var_name == "front_less": self.front_less_entry = entry elif var_name == "back_more": self.back_more_entry = entry elif var_name == "back_less": self.back_less_entry = entry # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_trend_analysis_content(self, parent: Frame): """创建趋势分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) for label in self.labels['trend_analysis']: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=label, width=12, anchor='w', font=('微软雅黑', 10, 'bold')).pack(side='left') entry = Entry(frame, width=30, state='readonly', readonlybackground='#f0f0f0') entry.pack(side='left', padx=5) var_name = label.replace(':', '').replace(' ', '_') setattr(self, f"{var_name}_entry", entry) # 直接保存到实例变量 if var_name == "sum_value": self.sum_value_entry = entry elif var_name == "prime_ratio": self.prime_ratio_entry = entry elif var_name == "odd_even_ratio": self.odd_even_ratio_entry = entry elif var_name == "zone_rec": self.zone_rec_entry = entry elif var_name == "consec_rec": self.consec_rec_entry = entry elif var_name == "hot_cold_rec": self.hot_cold_rec_entry = entry elif var_name == "hot_rec": self.hot_rec_entry = entry elif var_name == "cold_rec": self.cold_rec_entry = entry elif var_name == "trend_rec": self.trend_rec_entry = entry # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_number_generation_content(self, parent: Frame): """创建数字生成模块的动态内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) # 胆码输入区 dan_frame = Frame(content_frame) dan_frame.pack(fill='x', pady=5) # 前区胆码 front_dan_frame = Frame(dan_frame) front_dan_frame.pack(fill='x') Label(front_dan_frame, text="前区胆码:").pack(side='left') self.front_dan_entries = [] for i in range(5): entry = Entry(front_dan_frame, width=3) entry.pack(side='left', padx=2) self.front_dan_entries.append(entry) self.front_dan_entry = self.front_dan_entries[0] # 保存第一个条目引用 # 后区胆码 back_dan_frame = Frame(dan_frame) back_dan_frame.pack(fill='x') Label(back_dan_frame, text="后区胆码:").pack(side='left') self.back_dan_entries = [] for i in range(5): entry = Entry(back_dan_frame, width=3) entry.pack(side='left', padx=2) self.back_dan_entries.append(entry) self.back_dan_entry = self.back_dan_entries[0] # 保存第一个条目引用 # 生成的号码显示区 generated_frame = Frame(content_frame) generated_frame.pack(fill='x', pady=5) Label(generated_frame, text="生成号码:").pack(anchor='w') self.generated_labels = [] for i in range(1, 6): frame = Frame(generated_frame) frame.pack(fill='x') Label(frame, text=f"{i}.").pack(side='left') label = Label(frame, text="", width=30, anchor='w') label.pack(side='left') self.generated_labels.append(label) # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _run_module(self, module: str): """运行模块""" if module == "input_analysis": # 获取排除号码 exclude_front = self.exclude_front_entry.get() exclude_back = self.exclude_back_entry.get() # 发布排除号码事件 exclude_event = Event( event_id=int(time.time()), type=EventType.EXCLUDE_NUMBERS, source='main_ui', target='pool', data={ 'exclude_front': exclude_front, 'exclude_back': exclude_back } ) event_center.publish(exclude_event) # 在结果文本中记录 self.result_text.insert('end', f"已设置排除号码: 前区 {exclude_front}, 后区 {exclude_back}\n") # 发布模块运行事件 run_event = Event( event_id=int(time.time()), type=EventType.MODULE_RUN, source='main_ui', target=module ) event_center.publish(run_event) def _generate_recommend_numbers(self, exclude_front: str, exclude_back: str): """生成推荐号码(示例逻辑)""" # 实际应用中应调用分析模块生成推荐号码 # 这里简化为生成随机推荐号码 import random # 前区号码范围1-35 all_front = [str(idx) for idx in range(1, 36)] exclude_front_list = exclude_front.split() if exclude_front else [] available_front = [num for num in all_front if num not in exclude_front_list] # 后区号码范围1-12 all_back = [str(idx) for idx in range(1, 13)] exclude_back_list = exclude_back.split() if exclude_back else [] available_back = [num for num in all_back if num not in exclude_back_list] # 随机选择5个前区号码 if len(available_front) >= 5: recommend_front = random.sample(available_front, 5) else: recommend_front = random.sample(all_front, 5) # 随机选择2个后区号码 if len(available_back) >= 2: recommend_back = random.sample(available_back, 2) else: recommend_back = random.sample(all_back, 2) # 更新推荐号码显示 self.recommend_front_var.set(' '.join(sorted(recommend_front, key=int))) self.recommend_back_var.set(' '.join(sorted(recommend_back, key=int))) # 在结果文本中记录 self.result_text.insert('end', f"生成推荐号码: 前区 {self.recommend_front_var.get()}, 后区 {self.recommend_back_var.get()}\n") # 更新号码池 self._update_pool_with_recommendations(self.recommend_front_var.get(), self.recommend_back_var.get()) def _update_pool_with_recommendations(self, front: str, back: str): """用推荐号码更新号码池""" # 发布事件更新号码池 update_event = Event( event_id=int(time.time()), type=EventType.POOL_UPDATE, source='input_analysis', target='pool', data={ 'front_numbers': front, 'back_numbers': back } ) event_center.publish(update_event) # 在结果文本中记录 self.result_text.insert('end', "号码池已更新\n") def _clear_module_data(self, module: str): """清除模块数据""" if module == "input_analysis": if hasattr(self, 'front_entry') and self.front_entry: self.front_entry.delete(0, 'end') if hasattr(self, 'back_entry') and self.back_entry: self.back_entry.delete(0, 'end') if hasattr(self, 'exclude_front_entry') and self.exclude_front_entry: self.exclude_front_entry.delete(0, 'end') if hasattr(self, 'exclude_back_entry') and self.exclude_back_entry: self.exclude_back_entry.delete(0, 'end') if hasattr(self, 'recommend_front_var'): self.recommend_front_var.set('') if hasattr(self, 'recommend_back_var'): self.recommend_back_var.set('') if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') elif module == "combination_analysis": if hasattr(self, 'front_hot_entry') and self.front_hot_entry: self.front_hot_entry.delete(0, 'end') if hasattr(self, 'front_freq_entry') and self.front_freq_entry: self.front_freq_entry.delete(0, 'end') if hasattr(self, 'front_freq_rec_entry') and self.front_freq_rec_entry: self.front_freq_rec_entry.delete(0, 'end') if hasattr(self, 'back_hot_entry') and self.back_hot_entry: self.back_hot_entry.delete(0, 'end') if hasattr(self, 'back_freq_entry') and self.back_freq_entry: self.back_freq_entry.delete(0, 'end') if hasattr(self, 'back_infreq_rec_entry') and self.back_infreq_rec_entry: self.back_infreq_rec_entry.delete(0, 'end') if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') def _save_module_data(self, module: str): """保存模块数据""" try: data = {} if module == "input_analysis": data['front'] = self.front_entry.get() data['back'] = self.back_entry.get() data['exclude_front'] = self.exclude_front_entry.get() data['exclude_back'] = self.exclude_back_entry.get() data['recommend_front'] = self.recommend_front_var.get() data['recommend_back'] = self.recommend_back_var.get() data['result'] = self.result_text.get(1.0, 'end') elif module == "combination_analysis": data['front_hot'] = self.front_hot_entry.get() data['front_freq'] = self.front_freq_entry.get() data['front_freq_rec'] = self.front_freq_rec_entry.get() data['back_hot'] = self.back_hot_entry.get() data['back_freq'] = self.back_freq_entry.get() data['back_infreq_rec'] = self.back_infreq_rec_entry.get() data['result'] = self.result_text.get(1.0, 'end') # 其他模块数据收集... filename = f"{module}_data.json" with open(filename, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) messagebox.showinfo("保存成功", f"数据已保存到{filename}") except Exception as e: messagebox.showerror("保存失败", str(e)) logging.error(f"保存数据失败: {str(e)}", exc_info=True) def _handle_exclude_numbers(self, event: Event): """处理排除号码事件""" if event.data: exclude_front = event.data.get('exclude_front', '') exclude_back = event.data.get('exclude_back', '') # 更新排除号码显示 self.exclude_front_entry.delete(0, 'end') self.exclude_front_entry.insert(0, exclude_front) self.exclude_back_entry.delete(0, 'end') self.exclude_back_entry.insert(0, exclude_back) # 在结果文本中记录 self.result_text.insert('end', f"收到排除号码: 前区 {exclude_front}, 后区 {exclude_back}\n") def _handle_module_complete(self, event: Event): self.status_var.set(f"{event.source} 模块运行完成") if hasattr(self, 'result_text') and self.result_text: self.result_text.insert('end', f"\n{event.source} 模块已完成分析\n") def _on_module_renovate(self, module: str): """刷新模块""" if module == self.current_module: self._on_module_button_click(module) def _handle_ui_update(self, event: Event): """处理UI更新事件""" if not event.data or 'update_type' not in event.data: return update_type = event.data['update_type'] data = event.data.get('data', {}) # 处理核心变量更新 if update_type == 'organized_data': # 确保所有核心变量已初始化 if not hasattr(self, 'core_vars'): self.core_vars = { 'front_area': StringVar(), 'back_area': StringVar(), 'front_hot': StringVar(), 'front_cold': StringVar(), 'back_hot': StringVar(), 'back_cold': StringVar() } # 更新界面变量 self.core_vars['front_area'].set(str(data.get('front_numbers', []))) self.core_vars['back_area'].set(str(data.get('back_numbers', []))) self.core_vars['front_hot'].set(str(data.get('front_hot', []))) self.core_vars['front_cold'].set(str(data.get('front_cold', []))) self.core_vars['back_hot'].set(str(data.get('back_hot', []))) self.core_vars['back_cold'].set(str(data.get('back_cold', [])))
07-16
重新修改,生成完整代码要求:结合用户的思路,进行改错,要任意删除代码,只针对问题进行修改,生成完整代码。。问题 已重新声明上文定义的无用法的 'app'已重新声明上文定义的无用法的 '_handle_module_complete'已重新声明上文定义的无用法的 '_handle_exclude_numbers'已重新声明上文定义的无用法的 '_setup_ui'在 'EventType | EventType | EventType' 中找到引用 'ORGANIZE_DATA'在 'EventType | EventType | EventType' 中找到引用 'FREEZE_DATA'局部变量 'exclude_front' 可能在赋值前引用局部变量 'exclude_back' 可能在赋值前引用在 'GlobalConfig | GlobalConfig | GlobalConfig | GlobalConfig' 中找到引用 'UI_CONFIG'在 'GlobalConfig | GlobalConfig | GlobalConfig | GlobalConfig' 中找到引用 'MODULE1_ID'已重新声明上文定义的无用法的 '_handle_analysis_result'在 'GlobalConfig | GlobalConfig | GlobalConfig | GlobalConfig' 中找到引用 'MODULE3_ID'在 'GlobalConfig | GlobalConfig | GlobalConfig | GlobalConfig' 中找到引用 'MODULE3_ID'已重新声明上文定义的无用法的 '_run_module'局部变量 'exclude_front' 可能在赋值前引用局部变量 'exclude_back' 可能在赋值前引用类 'MainInterface' 的未解析的特性引用 '_update_pool_with_recommendations'在 'GlobalConfig | GlobalConfig | GlobalConfig | GlobalConfig' 中找到引用 'MODULE1_ID'已重新声明上文定义的无用法的 '_handle_ui_update' # ==================== 主界面修改 ==================== class DialogManager: def __init__(self): self.active_dialogs = {} # 保存所有激活的对话框实例 import tkinter as tk from tkinter import Tk, StringVar from typing import Optional, Union, Any from event_center import Event, EventType, event_center from global_config import GlobalConfig from dataclasses import dataclass @dataclass class DialogManager: active_dialogs: dict = None class AppContext: def __init__(self): self.dialog_manager = DialogManager() self.main_ui = None app = AppContext() class MainInterface: def __init__(self, root: Tk, pool: 'NumberPool'): self.root = root self.pool = pool self.left_panel = None self.center_paned = None self.right_panel = None self.core_vars = {} self.pool_vars = {} self.status_var = StringVar() self.dynamic_text: Optional[tk.Text] = None self.current_module: Optional[str] = None self._setup_ui() self._setup_event_handlers() self.module_instances = {} # 初始化控件列表 self.exclude_front_entries: list[tk.Entry] = [] self.exclude_back_entries: list[tk.Entry] = [] self.front_dan_entries: list[tk.Entry] = [] self.back_dan_entries: list[tk.Entry] = [] # 初始化结果文本控件 self.result_text: Optional[tk.Text] = None # 初始化变量 self.exclude_front_var = StringVar() self.exclude_back_var = StringVar() self.recommend_front_var = StringVar() self.recommend_back_var = StringVar() # 初始化框架 self.dynamic_content: Optional[tk.Frame] = None self.module_content_frame: Optional[tk.Frame] = None # 初始化推荐控件 self.front_recommend_less = tk.Entry(self.root) self.back_recommend_more = tk.Entry(self.root) self.back_recommend_less = tk.Entry(self.root) # 趋势分析控件 self.he_zhi_entry = tk.Entry(self.root) self.zhi_he_bi_entry = tk.Entry(self.root) self.ji_ou_bi_entry = tk.Entry(self.root) self.duan_qu_entry = tk.Entry(self.root) self.lian_hao_entry = tk.Entry(self.root) self.len_gre_entry = tk.Entry(self.root) self.hou_qu_re_hao_entry = tk.Entry(self.root) self.hou_qu_len_hao_entry = tk.Entry(self.root) self.qu_shi_entry = tk.Entry(self.root) # 数字生成控件 self.dan_ma_entry = tk.Entry(self.root) self.front_numbers_entry = tk.Entry(self.root) self.back_numbers_entry = tk.Entry(self.root) self.recommend_1 = tk.Entry(self.root) self.recommend_2 = tk.Entry(self.root) self.recommend_3 = tk.Entry(self.root) self.recommend_4 = tk.Entry(self.root) self.recommend_5 = tk.Entry(self.root) # 模块ID映射 self.module_ids = { 'input_analysis': getattr(GlobalConfig, 'MODULE1_ID', 'input_analysis'), 'combination_analysis': getattr(GlobalConfig, 'MODULE2_ID', 'combination_analysis'), 'follow_analysis': getattr(GlobalConfig, 'MODULE3_ID', 'follow_analysis'), 'trend_analysis': getattr(GlobalConfig, 'MODULE4_ID', 'trend_analysis'), 'number_generation': getattr(GlobalConfig, 'MODULE5_ID', 'number_generation'), } # 模块标签定义 self.labels = { 'input_analysis': [ "排除号码:", "前区:", "后区:", "推荐号码:", "前区:", "后区:", ], 'combination_analysis': [ "前数字频:", "前数字缺:", "后数字频:", "后数字缺:", "前频繁推:", "后低频推:", "生组合数:", "未组合码:" ], 'follow_analysis': [ "前推荐多:", "前推荐少:", "后推荐多:", "后推荐少:" ], 'trend_analysis': [ "和值:", "质合比:", "奇偶比:", "断区推荐:", "连号推荐:", "冷热推荐:", "后区热号:", "后区冷号:", "趋势号:" ], 'number_generation': [ "胆码:", "前区:", "后区:", "推荐5注号码:", "1:", "", "2:", "", "3:", "", "4:", "", "5:", "" ], } # 初始化条目引用 self.front_dan_entry: Optional[tk.Entry] = None self.back_dan_entry: Optional[tk.Entry] = None self.exclude_front_entry: Optional[tk.Entry] = None self.exclude_back_entry: Optional[tk.Entry] = None self.front_entry: Optional[tk.Entry] = None self.back_entry: Optional[tk.Entry] = None # 初始化 dialog_manager app.dialog_manager = DialogManager() app.main_ui = self self.root.deiconify() def _setup_ui(self): """设置界面布局""" pass # 实际的UI设置代码 def _setup_event_handlers(self): """设置事件处理器""" event_center.subscribe(EventType.MODULE_COMPLETE, self._handle_module_complete) event_center.subscribe(EventType.UI_UPDATE, self._handle_ui_update) event_center.subscribe(EventType.EXCLUDE_NUMBERS, self._handle_exclude_numbers) event_center.subscribe(EventType.ANALYSIS_RESULT, self._handle_analysis_result) # 添加缺失的事件处理器 event_center.subscribe("combination_analysis", self._handle_combination_event) event_center.subscribe("follow_analysis", self._handle_follow_event) event_center.subscribe("trend_analysis", self._handle_trend_event) event_center.subscribe("number_generation", self._handle_number_generation_event) def _handle_module_complete(self, event: Event): """处理模块完成事件""" pass # 实际的处理代码 def _handle_ui_update(self, event: Event): """处理UI更新事件""" pass # 实际的处理代码 def _handle_exclude_numbers(self, event: Event): """处理排除号码事件""" pass # 实际的处理代码 def _handle_analysis_result(self, event: Event): """处理分析结果事件""" pass # 实际的处理代码 def _handle_combination_event(self, event: Event): """处理组合分析事件""" pass # 实际的处理代码 def _handle_follow_event(self, event: Event): """处理跟随分析事件""" pass # 实际的处理代码 def _handle_trend_event(self, event: Event): """处理趋势分析事件""" pass # 实际的处理代码 def _handle_number_generation_event(self, event: Event): """处理数字生成事件""" pass # 实际的处理代码 def _handle_module_complete(self, event: Event): """处理模块完成事件""" self.status_var.set(f"{event.source} 模块运行完成") if event.source == "input_analysis" and hasattr(self, 'result_text') and self.result_text: # 更新推荐号码显示 if 'recommend_front' in event.data: self.recommend_front_var.set(event.data['recommend_front']) if 'recommend_back' in event.data: self.recommend_back_var.set(event.data['recommend_back']) # 在结果文本中记录 self.result_text.insert('end', f"\n{event.source} 模块已完成分析\n") self.result_text.insert('end', f"推荐号码: 前区 {self.recommend_front_var.get()}, 后区 {self.recommend_back_var.get()}\n") # 同步更新号码池 update_event = Event( event_id=int(time.time()), type=EventType.POOL_UPDATE, source='input_analysis', target='pool', data={ 'front_numbers': self.recommend_front_var.get(), 'back_numbers': self.recommend_back_var.get() } ) event_center.publish(update_event) self.result_text.insert('end', "号码池已同步更新\n") def _handle_exclude_numbers(self, event: Event): """处理排除号码更新事件""" self.status_var.set(f"{event.source} 模块更新排除号码") # 更新前区排除号码显示 if 'exclude_front' in event.data and hasattr(self, 'exclude_front_entries'): for i, entry in enumerate(self.exclude_front_entries): if i < len(event.data['exclude_front']): entry.delete(0, 'end') entry.insert(0, str(event.data['exclude_front'][i])) # 更新后区排除号码显示 if 'exclude_back' in event.data and hasattr(self, 'exclude_back_entries'): for i, entry in enumerate(self.exclude_back_entries): if i < len(event.data['exclude_back']): entry.delete(0, 'end') entry.insert(0, str(event.data['exclude_back'][i])) # 在结果区域记录 if hasattr(self, 'result_text'): self.result_text.insert('end', f"\n收到排除号码更新: 前区{event.data.get('exclude_front', [])}, 后区{event.data.get('exclude_back', [])}\n") def _setup_ui(self): self.root.title(f"大乐透智能分析平台 - {GlobalConfig.VERSION}") self.root.geometry("1400x800") # 添加主标题 title_frame = Frame(self.root) title_frame.pack(fill='x', pady=5) Label(title_frame, text="大乐透智能分析平台", font=('微软雅黑', 16, 'bold')).pack(expand=True) # 主容器 - 三栏布局 (修复点:使用 'horizontal' 替代 HORIZONTAL) main_container = PanedWindow(self.root, orient='horizontal', sashrelief=RAISED, sashwidth=5) main_container.pack(fill='both', expand=True, padx=5, pady=(0, 5)) # 左侧面板 self.left_panel = Frame(main_container, width=200, bg="#eaeaea") main_container.add(self.left_panel, minsize=150, stretch="never") # 中间内容区 self.center_paned = PanedWindow(main_container, orient=VERTICAL, sashrelief=RAISED, sashwidth=5) main_container.add(self.center_paned, minsize=500, stretch="always") # 右侧面板 self.right_panel = Frame(main_container, width=700, bg="#f5f5f5") main_container.add(self.right_panel, minsize=250, stretch="never") # 初始化各区域 self._setup_left_panel() self._setup_center_area() self._setup_right_panel() def _setup_left_panel(self): """初始化左侧模块按钮区""" module_names = { 'input_analysis': '1. 输入分析', 'combination_analysis': '2. 组合分析', 'follow_analysis': '3. 跟随分析', 'trend_analysis': '4. 趋势分析', 'number_generation': '5. 数字生成' } for module in GlobalConfig.MODULES: Button( self.left_panel, text=module_names[module], width=18, command=lambda m=module: self._on_module_button_click(m) ).pack(pady=3, padx=5, ipady=3) def _setup_center_area(self): """设置中间区域布局,分为上下两部分""" # 上半部分 - 核心区 (固定高度) self.core_frame = Frame(self.center_paned, bd=1, relief='solid') self.center_paned.add(self.core_frame, minsize=150, stretch="never") # 核心区内容 Label(self.core_frame, text="核心区", font=('微软雅黑', 12, 'bold')).pack(anchor='w', padx=5, pady=2) # 核心数据展示 self.core_vars = { 'front_area': StringVar(), 'back_area': StringVar(), 'front_hot': StringVar(), 'front_cold': StringVar(), 'back_hot': StringVar(), 'back_cold': StringVar() } for label, var_name in [ ("前区:", 'front_area'), ("后区:", 'back_area'), ("前区热号:", 'front_hot'), ("前区冷号:", 'front_cold'), ("后区热号:", 'back_hot'), ("后区冷号:", 'back_cold') ]: frame = Frame(self.core_frame) frame.pack(fill='x', padx=5, pady=2) Label(frame, text=label, width=10, anchor='w').pack(side='left') entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True) entry = Entry(entry_container, textvariable=self.core_vars[var_name], font=('微软雅黑', 10), state='readonly', readonlybackground='#f0f0f0', relief='sunken', bd=1) entry.pack(fill='x', expand=True) # 下半部分 - 动态区 self.dynamic_frame = Frame(self.center_paned, bd=1, relief='solid') self.center_paned.add(self.dynamic_frame, minsize=200, stretch="always") # 主容器使用Grid布局 self.dynamic_container = Frame(self.dynamic_frame) self.dynamic_container.pack(fill='both', expand=True) self.dynamic_container.grid_rowconfigure(0, weight=1) self.dynamic_container.grid_columnconfigure(0, weight=1) # 操作按钮放在右下角 self.btn_frame = Frame(self.dynamic_container) self.btn_frame.grid(row=1, column=0, sticky='se', pady=5, padx=5) Button(self.btn_frame, text="运行", width=8, command=self._run_current_module).pack(side='left', padx=2) Button(self.btn_frame, text="清除", width=8, command=self._clear_dynamic_content).pack(side='left', padx=2) Button(self.btn_frame, text="保存", width=8, command=self._save_dynamic_content).pack(side='left', padx=2) Button(self.btn_frame, text="刷新", width=8, command=self._refresh_dynamic).pack(side='left', padx=2) # 模块内容容器 - 确保先创建 self.module_content_frame = Frame(self.dynamic_container) self.module_content_frame.grid(row=0, column=0, sticky='nsew') # 初始化默认内容 self._init_default_dynamic_content() def _init_default_dynamic_content(self): """初始化默认动态区内容""" # 清除现有内容 for widget in self.module_content_frame.winfo_children(): widget.destroy() # 创建新内容 self.dynamic_content = Frame(self.module_content_frame) self.dynamic_content.pack(fill='both', expand=True) Label(self.dynamic_content, text="请从左侧选择分析模块", font=('微软雅黑', 12)).pack(expand=True, pady=50) def _on_module_button_click(self, module: str): """模块按钮点击事件处理""" self.status_var.set(f"打开 {module} 模块...") self.current_module = module # 确保 module_content_frame 存在且可操作 if not hasattr(self, 'module_content_frame') or self.module_content_frame is None: self.module_content_frame = Frame(self.dynamic_container) self.module_content_frame.grid(row=0, column=0, sticky='nsew') self._init_default_dynamic_content() logging.warning("module_content_frame 已紧急初始化") try: # 1️⃣ 彻底清除旧内容(包括残留按钮) for widget in self.module_content_frame.winfo_children(): widget.destroy() self.module_content_frame.update_idletasks() # 强制更新布局 # 2️⃣ 创建新内容容器 content_frame = Frame(self.module_content_frame) content_frame.pack(fill='both', expand=True) # 3️⃣ 根据模块类型创建具体内容 if module == "input_analysis": self._create_input_analysis_content(content_frame) elif module == "combination_analysis": self._create_combination_analysis_content(content_frame) elif module == "follow_analysis": self._create_follow_analysis_content(content_frame) elif module == "trend_analysis": self._create_trend_analysis_content(content_frame) elif module == "number_generation": self._create_number_generation_content(content_frame) # 4️⃣ 创建按钮容器(带唯一标识) # 先销毁已存在的按钮容器(严格检查类型和标记) for widget in self.module_content_frame.winfo_children(): if isinstance(widget, Frame) and hasattr(widget, 'is_button_container'): widget.destroy() # 创建新按钮容器并标记 btn_frame = Frame(self.module_content_frame) btn_frame.is_button_container = True # 标记为按钮容器 btn_frame.pack(side='bottom', fill='x', pady=5) btn_frame.pack_propagate(False) # 防止内部组件影响容器大小 # 按钮容器内部布局 btn_container = Frame(btn_frame) btn_container.pack(side='right') # 创建按钮(使用lambda时绑定当前模块状态) Button(btn_container, text="运行", width=8, command=lambda m=module: self._run_module(m)).pack(side='left', padx=2) Button(btn_container, text="清除", width=8, command=lambda m=module: self._clear_module_data(m)).pack(side='left', padx=2) Button(btn_container, text="保存", width=8, command=lambda m=module: self._save_module_data(m)).pack(side='left', padx=2) Button(btn_container, text="刷新", width=8, command=lambda m=module: self._on_module_button_click(m)).pack(side='left', padx=2) except Exception as e: # 5️⃣ 严重异常处理(强制重建界面) logging.critical(f"模块切换异常: {str(e)}", exc_info=True) if hasattr(self, 'module_content_frame'): self.module_content_frame.destroy() self.module_content_frame = Frame(self.dynamic_container) self.module_content_frame.grid(row=0, column=0, sticky='nsew') self._init_default_dynamic_content() def _run_current_module(self): """运行当前模块""" if self.current_module: self._run_module(self.current_module) def _clear_dynamic_content(self): """清除动态区内容""" if self.current_module: self._clear_module_data(self.current_module) # 额外确保清除结果文本框(如果存在) if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') def _save_dynamic_content(self): """保存动态区内容""" if self.current_module: self._save_module_data(self.current_module) else: messagebox.showinfo("提示", "请先选择并运行一个模块") def _refresh_dynamic(self): """刷新动态区内容""" if self.current_module: self._on_module_button_click(self.current_module) else: messagebox.showinfo("提示", "请先选择一个模块") def _organize_data(self): """整理号码池数据""" try: # 发布整理事件 event = Event( event_id=int(time.time()), type=EventType.ORGANIZE_DATA, source='main_ui', target='pool' ) event_center.publish(event) self.status_var.set("号码池数据已整理") except Exception as e: messagebox.showerror("整理失败", str(e)) logging.error(f"整理数据失败: {str(e)}", exc_info=True) def _freeze_data(self): """冻结号码池数据""" try: # 发布冻结事件 event = Event( event_id=int(time.time()), type=EventType.FREEZE_DATA, source='main_ui', target='pool' ) event_center.publish(event) self.status_var.set("号码池数据已冻结") except Exception as e: messagebox.showerror("冻结失败", str(e)) logging.error(f"冻结数据失败: {str(e)}", exc_info=True) def _run_module(self, module: str): """运行指定模块""" if module == "input_analysis": # 获取排除号码 exclude_front = self.exclude_front_entry.get() exclude_back = self.exclude_back_entry.get() # 发布排除号码事件 exclude_event = Event( event_id=int(time.time()), type=EventType.EXCLUDE_NUMBERS, source='main_ui', target='pool', data={ 'exclude_front': exclude_front, 'exclude_back': exclude_back } ) event_center.publish(exclude_event) # 在结果文本中记录 self.result_text.insert('end', f"已设置排除号码: 前区 {exclude_front}, 后区 {exclude_back}\n") run_event = Event( event_id=int(time.time()), type=EventType.MODULE_RUN, source='main_ui', target=module, # 确保 target 是当前模块名 data={ 'exclude_front': exclude_front, 'exclude_back': exclude_back } ) event_center.publish(run_event) def _create_ui_element(self, parent, label_text): """创建统一的UI元素(与核心区对齐)""" frame = Frame(parent) frame.pack(fill='x', pady=2) # 标签固定宽度与核心区对齐 Label(frame, text=label_text, width=10, anchor='w').pack(side='left') # 条目容器 - 宽度与核心区对齐 entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True) return entry_container def _setup_right_panel(self): """设置右侧号码池布局""" # 号码池标题 pool_title_frame = Frame(self.right_panel) pool_title_frame.pack(fill='x', pady=5) Label(pool_title_frame, text="号码池", font=('微软雅黑', 12, 'bold')).pack(anchor='w') # 号码池内容区(添加边框和2px内边距) pool_content = Frame(self.right_panel, bd=1, relief='solid', padx=2, pady=2) pool_content.pack(fill='both', expand=True, padx=5, pady=5) # 创建Canvas和Scrollbar canvas = Canvas(pool_content, highlightthickness=0) scrollbar = Scrollbar(pool_content, orient="vertical", command=canvas.yview) scrollable_frame = Frame(canvas) scrollable_frame.bind( "<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")) ) canvas.create_window((0, 0), window=scrollable_frame, anchor="nw") canvas.configure(yscrollcommand=scrollbar.set) # 号码池项目 - 优化布局和样式(带2px右边距) for label, var_name, row_id in GlobalConfig.UI_CONFIG: frame = Frame(scrollable_frame) frame.grid(row=row_id, column=0, sticky='ew', padx=0, pady=1) # 移除水平padding # 左侧标签(固定宽度为8个字符) lbl = Label(frame, text=label, width=8, anchor='w') lbl.pack(side='left', padx=(0, 5)) # 标签右侧留5px间距 # 右侧输入框容器(带2px右边距) entry_container = Frame(frame) entry_container.pack(side='left', fill='x', expand=True, padx=(0, 2)) var = StringVar() self.pool_vars[var_name] = var entry = Entry(entry_container, textvariable=var, font=('微软雅黑', 9), state='readonly', readonlybackground='#f0f0f0', relief='sunken', bd=1) entry.pack(fill='x', expand=True) canvas.pack(side="left", fill="both", expand=True) scrollbar.pack(side="right", fill="y") # 底部按钮区 btn_frame = Frame(self.right_panel) btn_frame.pack(fill='x', pady=5) Button(btn_frame, text="整理", width=10, command=self._organize_data).pack(side='left', padx=5) Button(btn_frame, text="冻结", width=10, command=self._freeze_data).pack(side='left', padx=5) Button(btn_frame, text="导出", width=10).pack(side='left', padx=5) def _validate_number(self, text: str, min_val: int, max_val: int) -> bool: """验证输入的数字是否在指定范围内""" if text == "": return True # 允许空输入(删除操作) if not text.isdigit(): return False num = int(text) return min_val <= num <= max_val def _create_input_analysis_content(self, parent: Frame): """创建输入分析模块内容 - 增加模块ID标识""" # 主容器使用Grid布局 main_frame = Frame(parent) main_frame.pack(fill='both', expand=True) # 添加模块ID标识(右上角) module_id_label = Label(main_frame, text=f"模块ID: {GlobalConfig.MODULE1_ID}", font=('微软雅黑', 8), fg='gray') module_id_label.pack(anchor='ne', padx=10, pady=5) # === 排除号码区 === exclude_frame = LabelFrame(main_frame, text=" 排除号码 ", font=('微软雅黑', 12, 'bold')) exclude_frame.pack(fill='x', padx=20, pady=10, ipady=5) # 使用预定义的标签文本 labels = self.labels['input_analysis'] # 排除号码标签 Label(exclude_frame, text=labels[0], font=('微软雅黑', 10, 'bold')).pack(anchor='w', padx=10, pady=(5, 0)) # 前区排除 Label(exclude_frame, text=labels[1], font=('微软雅黑', 10)).pack(anchor='w', padx=10, pady=5) front_entries_frame = Frame(exclude_frame) front_entries_frame.pack(fill='x', padx=10, pady=5) self.exclude_front_entries = [] for i in range(10): # 10个前区输入框 entry_frame = Frame(front_entries_frame) entry_frame.pack(side='left', padx=2) Label(entry_frame, text=f"{i + 1}:").pack(side='left') entry = Entry(entry_frame, width=3, font=('微软雅黑', 10)) entry.pack(side='left') # 添加验证函数 - 前区限制1-35 entry.config(validate="key", validatecommand=( entry.register(lambda text: self._validate_number(text, 1, 35)), '%P')) entry.bind("<KeyRelease>", self._auto_format_entry) entry.bind("<Left>", lambda e, d=-1: self._navigate_entry(e, d)) entry.bind("<Right>", lambda e, d=1: self._navigate_entry(e, d)) self.exclude_front_entries.append(entry) # 后区排除 Label(exclude_frame, text=labels[2], font=('微软雅黑', 10)).pack(anchor='w', padx=10, pady=(10, 5)) back_entries_frame = Frame(exclude_frame) back_entries_frame.pack(fill='x', padx=10, pady=5) self.exclude_back_entries = [] for i in range(10): # 10个后区输入框 entry_frame = Frame(back_entries_frame) entry_frame.pack(side='left', padx=2) Label(entry_frame, text=f"{i + 1}:").pack(side='left') entry = Entry(entry_frame, width=3, font=('微软雅黑', 10)) entry.pack(side='left') # 添加验证函数 - 后区限制1-12 entry.config(validate="key", validatecommand=( entry.register(lambda text: self._validate_number(text, 1, 12)), '%P')) entry.bind("<KeyRelease>", self._auto_format_entry) entry.bind("<Left>", lambda e, d=-1: self._navigate_entry(e, d)) entry.bind("<Right>", lambda e, d=1: self._navigate_entry(e, d)) self.exclude_back_entries.append(entry) # 加载保存的数据 - 确保正确处理数据格式 if os.path.exists(GlobalConfig.MODULE1_SAVE_PATH): try: with open(GlobalConfig.MODULE1_SAVE_PATH, 'r', encoding='utf-8') as f: saved_data = json.load(f) # 恢复前区排除号码 - 确保正确处理空值和格式 if 'exclude_front' in saved_data: for i, num in enumerate(saved_data['exclude_front']): if i < len(self.exclude_front_entries) and num: # 确保有值 try: formatted_num = f"{int(num):02d}" # 确保两位数格式 self.exclude_front_entries[i].delete(0, 'end') self.exclude_front_entries[i].insert(0, formatted_num) except ValueError: continue # 跳过无效数字 # 恢复后区排除号码 - 确保正确处理空值和格式 if 'exclude_back' in saved_data: for i, num in enumerate(saved_data['exclude_back']): if i < len(self.exclude_back_entries) and num: # 确保有值 try: formatted_num = f"{int(num):02d}" # 确保两位数格式 self.exclude_back_entries[i].delete(0, 'end') self.exclude_back_entries[i].insert(0, formatted_num) except ValueError: continue # 跳过无效数字 except Exception as e: logging.error(f"加载保存数据失败: {str(e)}") messagebox.showerror("加载失败", f"无法加载保存的数据: {str(e)}") # 确保保存了排除号码输入框的引用 self.exclude_front_entry = self.exclude_front_entries[0] # 保存第一个前区排除输入框 self.exclude_back_entry = self.exclude_back_entries[0] # 保存第一个后区排除输入框 # === 推荐号码区 === recommend_frame = LabelFrame(main_frame, text=" 推荐号码 ", font=('微软雅黑', 12, 'bold')) recommend_frame.pack(fill='x', padx=20, pady=10, ipady=5) # 推荐号码标签 Label(recommend_frame, text=labels[3], font=('微软雅黑', 10, 'bold')).pack(anchor='w', padx=10, pady=(5, 0)) # 前区推荐 front_rec_frame = Frame(recommend_frame) front_rec_frame.pack(fill='x', padx=10, pady=5) Label(front_rec_frame, text=labels[4], font=('微软雅黑', 10)).pack(side='left') self.recommend_front_var = StringVar() Entry(front_rec_frame, textvariable=self.recommend_front_var, state='readonly', font=('微软雅黑', 10), readonlybackground='#f0f5f0').pack(side='left', fill='x', expand=True, padx=5) # 后区推荐 back_rec_frame = Frame(recommend_frame) back_rec_frame.pack(fill='x', padx=10, pady=5) Label(back_rec_frame, text=labels[5], font=('微软雅黑', 10)).pack(side='left') self.recommend_back_var = StringVar() Entry(back_rec_frame, textvariable=self.recommend_back_var, state='readonly', font=('微软雅黑', 10), readonlybackground='#f0f5f0').pack(side='left', fill='x', expand=True, padx=5) # === 结果区 === result_frame = LabelFrame(main_frame, text=" 分析结果 ", font=('微软雅黑', 12, 'bold')) result_frame.pack(fill='both', expand=True, padx=20, pady=10, ipady=5) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word', font=('微软雅黑', 10)) self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) # 添加初始提示 self.result_text.insert('end', "请设置排除号码后点击'运行'按钮开始分析\n") # 强制刷新界面 self.root.update_idletasks() def _handle_analysis_result(self, event: Event): if event.target == self.current_module: result = event.data self.recommend_front_var.set(' '.join(map(str, result.get('recommended_fronts', [])))) self.recommend_back_var.set(' '.join(map(str, result.get('recommended_backs', [])))) self.result_text.insert('end', f"前区推荐号码: {self.recommend_front_var.get()}\n") self.result_text.insert('end', f"后区推荐号码: {self.recommend_back_var.get()}\n") self.result_text.see('end') def _handle_entry_input(self, event): """处理输入框相关事件的总入口""" if event.keysym in ('Left', 'Right'): # 处理方向键导航 self._navigate_entry(event, 1 if event.keysym == 'Right' else -1) else: # 处理输入自动格式化 self._auto_format_entry(event) def _auto_format_entry(self, event): """ 自动格式化输入框内容 功能: 1. 自动将1-9的数字补零显示为01-09 2. 输入满2位后自动跳到下一个输入框 """ entry = event.widget current = entry.get().strip() if current.isdigit(): # 只处理数字输入 # 自动补零处理 formatted = self._format_number(current) if formatted != current: entry.delete(0, 'end') entry.insert(0, formatted) # 输入满2位后自动跳转 if len(current) == 2: self._focus_adjacent_entry(event.widget, 1) # 正向跳转 def _focus_adjacent_entry(self, current_entry, direction): """ 焦点跳转到相邻输入框 :param current_entry: 当前输入框控件 :param direction: 跳转方向 (1:下一个, -1:上一个) """ all_entries = self.exclude_front_entries + self.exclude_back_entries try: current_index = all_entries.index(current_entry) target_index = current_index + direction if 0 <= target_index < len(all_entries): all_entries[target_index].focus() except ValueError: pass def _navigate_entry(self, event, direction): """使用方向键在输入框间导航""" self._focus_adjacent_entry(event.widget, direction) def _format_number(self, num_str: str) -> str: """ 格式化数字为两位数 :param num_str: 输入的数字字符串 :return: 格式化后的两位数字符串 """ if not num_str.isdigit(): return num_str # 非数字处理 num = int(num_str) if 1 <= num <= 9: # 1-9的数字补零 return f"0{num}" return str(num) if num > 0 else num_str # 保留0和负数原样 def _create_combination_analysis_content(self, parent: Frame): """创建组合分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) # 使用预定义的labels for label in self.labels['combination_analysis']: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=label, width=12, anchor='w', font=('微软雅黑', 10, 'bold')).pack(side='left') entry = Entry(frame, width=30, state='readonly', readonlybackground='#f0f0f0') entry.pack(side='left', padx=5) # 保存对控件的引用 var_name = label.replace(':', '').replace(' ', '') setattr(self, f"{var_name}_entry", entry) # 直接保存到实例变量 if var_name == "前区热号": self.front_hot_entry = entry elif var_name == "前数字频": self.front_freq_entry = entry elif var_name == "前频繁推": self.front_freq_rec_entry = entry elif var_name == "后区热号": self.back_hot_entry = entry elif var_name == "后数字频": self.back_freq_entry = entry elif var_name == "后低频推": self.back_in_freq_rec_entry = entry # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_follow_analysis_content(self, parent: Frame): """创建跟随分析模块UI - 确保标签匹配""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True) # 使用与数据字典相同的标签 labels = ["前推荐多", "前推荐少", "后推荐多", "后推荐少"] # 创建显示区域 for label in labels: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=f"{label}:", width=10).pack(side='left') entry = Entry(frame, state='readonly') entry.pack(side='left', fill='x', expand=True) # 保存引用以便更新 setattr(self, f"{label}_entry", entry) def _handle_module3_run(self, event: Event): """处理模块3运行事件""" if event.token == GlobalConfig.MODULE3_ID: # 确保只在模块3里界面处理 if self.current_module == GlobalConfig.MODULE3_ID: # 更新UI状态 self.status_var.set("模块3分析中...") # 在动态区显示状态 if hasattr(self, 'dynamic_text'): self.dynamic_text.insert('end', f"收到模块3运行指令 [Token: {event.token}]\n") # 结果显示区(包含按钮) result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_trend_analysis_content(self, parent: Frame): """创建趋势分析模块的特定内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) for label in self.labels['trend_analysis']: frame = Frame(content_frame) frame.pack(fill='x', pady=2) Label(frame, text=label, width=12, anchor='w', font=('微软雅黑', 10, 'bold')).pack(side='left') entry = Entry(frame, width=30, state='readonly', readonlybackground='#f0f0f0') entry.pack(side='left', padx=5) var_name = label.replace(':', '').replace(' ', '') setattr(self, f"{var_name}_entry", entry) # 直接保存到实例变量 if var_name == "和值": self.sum_value_entry = entry elif var_name == "质合比": self.prime_ratio_entry = entry elif var_name == "奇偶比": self.odd_even_ratio_entry = entry elif var_name == "断区推荐": self.zone_rec_entry = entry elif var_name == "连号推荐": self.con_sec_rec_entry = entry elif var_name == "冷热推荐": self.hot_cold_rec_entry = entry elif var_name == "后区热号": self.hot_rec_entry = entry elif var_name == "后区冷号": self.cold_rec_entry = entry elif var_name == "趋势号": self.trend_rec_entry = entry # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _create_number_generation_content(self, parent: Frame): """创建数字生成模块的动态内容""" content_frame = Frame(parent) content_frame.pack(fill='both', expand=True, padx=10, pady=10) # 胆码输入区 dan_frame = Frame(content_frame) dan_frame.pack(fill='x', pady=5) # 前区胆码 front_dan_frame = Frame(dan_frame) front_dan_frame.pack(fill='x') Label(front_dan_frame, text="前区胆码:").pack(side='left') self.front_dan_entries = [] for i in range(5): entry = Entry(front_dan_frame, width=3) entry.pack(side='left', padx=2) self.front_dan_entries.append(entry) self.front_dan_entry = self.front_dan_entries[0] # 保存第一个条目引用 # 后区胆码 back_dan_frame = Frame(dan_frame) back_dan_frame.pack(fill='x') Label(back_dan_frame, text="后区胆码:").pack(side='left') self.back_dan_entries = [] for i in range(5): entry = Entry(back_dan_frame, width=3) entry.pack(side='left', padx=2) self.back_dan_entries.append(entry) self.back_dan_entry = self.back_dan_entries[0] # 保存第一个条目引用 # 生成的号码显示区 generated_frame = Frame(content_frame) generated_frame.pack(fill='x', pady=5) Label(generated_frame, text="生成号码:").pack(anchor='w') self.generated_labels = [] for i in range(1, 6): frame = Frame(generated_frame) frame.pack(fill='x') Label(frame, text=f"{i}. ").pack(side='left') label = Label(frame, text="", width=30, anchor='w') label.pack(side='left') self.generated_labels.append(label) # 结果显示区 result_frame = Frame(content_frame) result_frame.pack(fill='both', expand=True) scrollbar = Scrollbar(result_frame) scrollbar.pack(side='right', fill='y') self.result_text = Text(result_frame, yscrollcommand=scrollbar.set, wrap='word') self.result_text.pack(fill='both', expand=True) scrollbar.config(command=self.result_text.yview) def _run_module(self, module: str): try: if module == "input_analysis": # 获取并格式化排除号码 exclude_front_list = [] for entry in self.exclude_front_entries: num = entry.get().strip() if num: # 只处理非空输入 exclude_front_list.append(num) exclude_back_list = [] for entry in self.exclude_back_entries: num = entry.get().strip() if num: # 只处理非空输入 exclude_back_list.append(num) exclude_front = ' '.join(exclude_front_list) exclude_back = ' '.join(exclude_back_list) # 在结果文本中记录 self.result_text.insert('end', f"正在运行分析...\n排除号码: 前区 {exclude_front}, 后区 {exclude_back}\n") # 发布模块运行事件,确保target正确 run_event = Event( event_id=int(time.time()), type=EventType.MODULE_RUN, source='main_ui', target=module # 确保target是当前模块名 ) event_center.publish(run_event) # 发布模块运行事件(包含完整数据) run_event = Event( event_id=int(time.time()), type=EventType.MODULE_RUN, source='main_ui', target=module, data={ 'exclude_front': exclude_front, 'exclude_back': exclude_back } ) event_center.publish(run_event) # 记录事件发布 self.result_text.insert('end', "已发送运行指令和排除号码数据\n") except Exception as e: logging.error(f"运行模块失败: {str(e)}", exc_info=True) messagebox.showerror("运行失败", f"无法运行模块: {str(e)}") def _generate_recommend_numbers(self, exclude_front: str, exclude_back: str): """生成推荐号码(示例逻辑)""" # 实际应用中应调用分析模块生成推荐号码 # 这里简化为生成随机推荐号码 import random # 前区号码范围1-35 all_front = [str(idx) for idx in range(1, 36)] exclude_front_list = exclude_front.split() if exclude_front else [] available_front = [num for num in all_front if num not in exclude_front_list] # 后区号码范围1-12 all_back = [str(idx) for idx in range(1, 13)] exclude_back_list = exclude_back.split() if exclude_back else [] available_back = [num for num in all_back if num not in exclude_back_list] # 随机选择5个前区号码 if len(available_front) >= 5: recommend_front = random.sample(available_front, 5) else: recommend_front = random.sample(all_front, 5) # 随机选择2个后区号码 if len(available_back) >= 2: recommend_back = random.sample(available_back, 2) else: recommend_back = random.sample(all_back, 2) # 更新推荐号码显示 self.recommend_front_var.set(' '.join(sorted(recommend_front, key=int))) self.recommend_back_var.set(' '.join(sorted(recommend_back, key=int))) # 在结果文本中记录 self.result_text.insert('end', f"生成推荐号码: 前区 {self.recommend_front_var.get()}, 后区 {self.recommend_back_var.get()}\n") # 更新号码池 self._update_pool_with_recommendations(self.recommend_front_var.get(), self.recommend_back_var.get()) def update_recommendations(self, fronts: List[int], backs: List[int]): """更新推荐号码显示(使用号码池路径保存)""" formatted_fronts = [str(num).zfill(2) for num in fronts] formatted_backs = [str(num).zfill(2) for num in backs] self.recommend_front_var.set(' '.join(formatted_fronts)) self.recommend_back_var.set(' '.join(formatted_backs)) # 保存到号码池文件 try: pool_data = { 'recommended_fronts': formatted_fronts, 'recommended_backs': formatted_backs, 'module_id': GlobalConfig.MODULE1_ID, 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } with open(GlobalConfig.POOL_SAVE_PATH, 'w', encoding='utf-8') as f: json.dump(pool_data, f, indent=2, ensure_ascii=False) logging.info(f"推荐号码已保存到号码池: {GlobalConfig.POOL_SAVE_PATH}") except Exception as e: logging.error(f"保存号码池失败: {str(e)}") def _clear_module_data(self, module: str): """清除模块数据 - 确保清除所有输入框""" if module == "input_analysis": # 清除前区排除号码 for entry in self.exclude_front_entries: entry.delete(0, 'end') # 清除后区排除号码 for entry in self.exclude_back_entries: entry.delete(0, 'end') # 清除推荐号码显示 if hasattr(self, 'recommend_front_var'): self.recommend_front_var.set('') if hasattr(self, 'recommend_back_var'): self.recommend_back_var.set('') # 清除结果文本 if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') elif module == "combination_analysis": if hasattr(self, 'front_hot_entry') and self.front_hot_entry: self.front_hot_entry.delete(0, 'end') if hasattr(self, 'front_freq_entry') and self.front_freq_entry: self.front_freq_entry.delete(0, 'end') if hasattr(self, 'front_freq_rec_entry') and self.front_freq_rec_entry: self.front_freq_rec_entry.delete(0, 'end') if hasattr(self, 'back_hot_entry') and self.back_hot_entry: self.back_hot_entry.delete(0, 'end') if hasattr(self, 'back_freq_entry') and self.back_freq_entry: self.back_freq_entry.delete(0, 'end') if hasattr(self, 'back_in_freq_rec_entry') and self.back_in_freq_rec_entry: self.back_in_freq_rec_entry.delete(0, 'end') if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') if hasattr(self, 'result_text') and self.result_text: self.result_text.delete(1.0, 'end') if hasattr(self, 'front_entry') and self.front_entry: self.front_entry.delete(0, 'end') if hasattr(self, 'back_entry') and self.back_entry: self.back_entry.delete(0, 'end') if hasattr(self, 'exclude_front_entry') and self.exclude_front_entry: self.exclude_front_entry.delete(0, 'end') if hasattr(self, 'exclude_back_entry') and self.exclude_back_entry: self.exclude_back_entry.delete(0, 'end') def _save_module_data(self, module: str): """保存模块数据 - 根据同模块保存对应的数据到指定路径""" try: data = {} filename = "" if module == "input_analysis": # 收集排除号码 - 只保存非空值 exclude_front_list = [entry.get().strip() for entry in self.exclude_front_entries if entry.get().strip()] exclude_back_list = [entry.get().strip() for entry in self.exclude_back_entries if entry.get().strip()] data = { 'exclude_front': exclude_front_list, 'exclude_back': exclude_back_list, 'module_id': GlobalConfig.module1_id, 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } filename = GlobalConfig.MODULE1_SAVE_PATH elif module == "combination_analysis": data = { 'front_hot': self.front_hot_entry.get(), 'front_freq': self.front_freq_entry.get(), 'front_freq_rec': self.front_freq_rec_entry.get(), 'back_hot': self.back_hot_entry.get(), 'back_freq': self.back_freq_entry.get(), 'back_in_freq_rec': self.back_in_freq_rec_entry.get(), 'result': self.result_text.get(1.0, 'end').strip(), 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } filename = GlobalConfig.MODULE2_SAVE_PATH elif module == "follow_analysis": data = { "前推荐多": self.front_recommend_more.get(), "前推荐少": self.front_recommend_less.get(), "后推荐多": self.back_recommend_more.get(), "后推荐少": self.back_recommend_less.get(), 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } filename = GlobalConfig.MODULE3_SAVE_PATH elif module == "trend_analysis": data = { "和值": self.he_zhi_entry.get(), "质合比": self.zhi_he_bi_entry.get(), "奇偶比": self.ji_ou_bi_entry.get(), "断区推荐": self.duan_qu_entry.get(), "连号推荐": self.lian_hao_entry.get(), "冷热推荐": self.len_gre_entry.get(), "后区热号": self.hou_qu_re_hao_entry.get(), "后区冷号": self.hou_qu_len_hao_entry.get(), "趋势号": self.qu_shi_entry.get(), 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } filename = GlobalConfig.MODULE4_SAVE_PATH elif module == "number_generation": data = { "胆码": self.dan_ma_entry.get(), "前区": self.front_numbers_entry.get(), "后区": self.back_numbers_entry.get(), "推荐5注号码": { "1": self.recommend_1.get(), "2": self.recommend_2.get(), "3": self.recommend_3.get(), "4": self.recommend_4.get(), "5": self.recommend_5.get() }, 'timestamp': time.strftime("%Y-%m-%d %H:%M:%S") } filename = GlobalConfig.MODULE5_SAVE_PATH # 确保目录存在 os.makedirs(os.path.dirname(filename), exist_ok=True) # 保存数据 with open(filename, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) messagebox.showinfo("保存成功", f"数据已保存到:\n{filename}") except Exception as e: messagebox.showerror("保存失败", f"无法保存数据: {str(e)}") logging.error(f"保存数据失败: {str(e)}", exc_info=True) def _on_module_renovate(self, module: str): """刷新模块""" if module == self.current_module: self._on_module_button_click(module) def _handle_ui_update(self, event: Event): update_type = event.data.get('update_type') # 添加 update_type 的定义 data = event.data.get('data', {}) # 确保 data 被赋值,避免未定义问题 if event.data.get('update_type') == 'recommendations': data = event.data.get('data', {}) front_rec = data.get('recommendations', {}).get('front_rec', []) back_rec = data.get('recommendations', {}).get('back_rec', []) self.recommend_front_var.set(' '.join(map(str, front_rec))) self.recommend_back_var.set(' '.join(map(str, back_rec))) # 处理核心变量更新 if update_type == 'organized_data': # 确保所有核心变量已初始化 if not hasattr(self, 'core_vars'): self.core_vars = { 'front_area': StringVar(), 'back_area': StringVar(), 'front_hot': StringVar(), 'front_cold': StringVar(), 'back_hot': StringVar(), 'back_cold': StringVar() } # 更新界面变量 self.core_vars['front_area'].set(str(data.get('front_numbers', []))) self.core_vars['back_area'].set(str(data.get('back_numbers', []))) self.core_vars['front_hot'].set(str(data.get('front_hot', []))) self.core_vars['front_cold'].set(str(data.get('front_cold', []))) self.core_vars['back_hot'].set(str(data.get('back_hot', []))) self.core_vars['back_cold'].set(str(data.get('back_cold', [])))
07-24
修改问题:未解析的引用 'TrendAnalysisModule',未解析的引用 'NumberGenerationModule',未解析的引用 'TrendAnalysisModule',未解析的引用 'NumberGenerationModule',未解析的引用 'Label',未解析的引用 'time',未解析的引用 'os'未解析的引用 'os'未解析的引用 'os'未解析的引用 'os'未解析的引用 'filename'未解析的引用 'filename'未解析的引用 'data'未解析的引用 'data',未解析的引用 'StringVar'未解析的引用 'StringVar'未解析的引用 'StringVar'未解析的引用 'StringVar'未解析的引用 'Frame'未解析的引用 'Frame'未解析的引用 'Frame'类 'MainInterface' 的未解析的特性引用 '_setup_main_window',类 'MainInterface' 的未解析的特性引用 '_setup_main_window'类 'MainInterface' 的未解析的特性引用 '_setup_left_panel',类 'MainInterface' 的未解析的特性引用 '_setup_center_area',类 'MainInterface' 的未解析的特性引用 '_setup_right_panel',,形参 'module_config' 未填,类 'MainInterface' 的未解析的特性引用 '_setup_main_window',类 'MainInterface' 的未解析的特性引用 '_setup_left_panel',类 'MainInterface' 的未解析的特性引用 '_setup_center_area',类 'MainInterface' 的未解析的特性引用 '_setup_right_panel',代码#!/usr/bin/env python3 # -*- coding: utf-8 -*- import json import tkinter as tk import datetime import pandas as pd import logging from pathlib import Path from typing import Dict, Any, Callable from project.core.global_config import GlobalConfig from project.core.number_pool import NumberPool from project.core.app_context import app_context from project.core.event_center import EventCenter from project.modules.input_analysis import InputAnalysisModule from project.modules.combination_analysis import CombinationAnalysisModule from project.modules.follow_analysis import FollowAnalysisModule from project.modules.trend_analysis import TrendAnalyzer from project.modules.number_generation import NumberGenerator from project.ui.dialog_manager import DialogManager # 配置日志记录器 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) class MainInterface: def __init__(self, root_window: tk.Tk, number_pool: NumberPool): self.root = root_window self.pool = number_pool self.app = app_context self._callbacks: Dict[str, Callable] = {} self._dynamic_content: Dict[str, Any] = {} self._module_states: Dict[str, Dict] = {} self.DEBUG_MODE = False # 添加DEBUG_MODE属性 self._init_ui_components() # 初始化UI组件 self._init_modules() # 初始化模块系统 self._init_default_dynamic_content() # 初始化动态内容 # 初始化事件中心 self.app.event_center = GlobalConfig.init_event_center() # 初始化UI变量 self._init_ui_variables() # 创建主容器 self.main_frame = tk.Frame(root_window) self.main_frame.pack(fill=tk.BOTH, expand=True) # 初始化UI组件 self._init_ui_components() # 初始化动态内容 self._init_default_dynamic_content() # 初始化所有模块 self._init_modules() # 恢复模块状态 self.restore_module_state() # 设置应用引用 app_context.dialog_manager = DialogManager() app_context.main_ui = self def _init_ui_components(self): """初始化所有UI组件""" self._setup_main_window() self._setup_left_panel() self._setup_center_area() self._setup_right_panel() logger.info("UI组件初始化完成") # 标题栏 self.title_label = tk.Label( self.main_frame, text=GlobalConfig.VERSION, font=("Arial", 16, "bold") ) # 主内容区域 self.content_frame = tk.Frame(self.main_frame) # 状态栏 self.status_bar = tk.Label( self.main_frame, text="就绪", bd=1, relief=tk.SUNKEN, anchor=tk.W ) # 布局组件 self.title_label.pack(pady=10) self.content_frame.pack(fill=tk.BOTH, expand=True) self.status_bar.pack(fill=tk.X) def _init_default_dynamic_content(self): """初始化默认动态内容""" self._dynamic_content = { 'recommendations': {'front': [], 'back': []}, 'analysis_results': {}, 'module_buttons': {} } def restore_module_state(self): """从配置文件恢复模块状态""" try: # 使用正确的配置路径获取方法 state_file = GlobalConfig.CONFIG_PATHS.get('MODULE_STATE', 'module_state.json') if Path(state_file).exists(): with open(state_file, 'r', encoding='utf-8') as f: self._module_states = json.load(f) logger.info("成功恢复模块状态") except Exception as e: logger.error(f"恢复模块状态失败: {e}") def _update_pool_with_recommendations(self): """用推荐数据更新号码池""" if not self._dynamic_content.get('recommendations'): return front_rec = self._dynamic_content['recommendations'].get('front', []) back_rec = self._dynamic_content['recommendations'].get('back', []) if front_rec or back_rec: self.pool.update({ 'front_numbers': front_rec, 'back_numbers': back_rec }) logger.info("号码池已更新推荐号码") def register_callback(self, event_type: str, callback: Callable) -> None: """注册回调函数""" self._callbacks[event_type] = callback def _init_modules(self): """初始化模块系统""" self.modules = { GlobalConfig.MODULE1_ID: InputAnalysisModule(), GlobalConfig.MODULE2_ID: CombinationAnalysisModule(), GlobalConfig.MODULE3_ID: FollowAnalysisModule(), GlobalConfig.MODULE4_ID: TrendAnalysisModule(), GlobalConfig.MODULE5_ID: NumberGenerationModule() } logger.info("模块系统初始化完成") self.module_content_frame = tk.Frame(self.main_frame) self.module_content_frame.pack(fill=tk.BOTH, expand=True) # 模块初始化函数 - 修复参数传递问题 def init_module(module_class, module_id, extra_params=None): # 创建模块配置对象 config = { 'module_id': module_id, 'labels': GlobalConfig.get_module_labels(module_id) } # 合并额外参数 if extra_params: config.update(extra_params) # 直接传递整个配置对象,而是拆分为关键字参数 module = module_class(module_config=config) self._register_module_callback( module, "analysis_result", self._handle_analysis_result ) return module # 模块1: 输入分析 self.module1 = init_module(InputAnalysisModule, GlobalConfig.MODULE1_ID) # 模块2: 组合分析 self.module2 = init_module( CombinationAnalysisModule, GlobalConfig.MODULE2_ID, {'event_center': self.app.event_center} ) # 模块3: 跟随分析 self.module3 = init_module(FollowAnalysisModule, GlobalConfig.MODULE3_ID) # 模块4: 趋势分析 self.module4 = init_module( TrendAnalyzer, GlobalConfig.MODULE4_ID, { 'df': pd.DataFrame(), 'event_center': self.app.event_center, 'event_handlers': { 'run_analysis': self._handle_run_analysis, 'get_results': self._handle_get_results } } ) # 模块5: 数字生成 self.module5 = init_module(NumberGenerator, GlobalConfig.MODULE5_ID) # 保存模块引用 self.app.modules = { GlobalConfig.MODULE1_ID: self.module1, GlobalConfig.MODULE2_ID: self.module2, GlobalConfig.MODULE3_ID: self.module3, GlobalConfig.MODULE4_ID: self.module4, GlobalConfig.MODULE5_ID: self.module5 } def _register_module_callback(self, module: Any, event_type: str, callback: Callable) -> None: """统一注册模块回调""" if hasattr(module, 'register_callback'): module.register_callback(event_type, callback) else: logger.warning(f"模块 {type(module).__name__} 没有 register_callback 方法") def _handle_run_analysis(self, event_data: Dict[str, Any]) -> None: """处理运行分析请求""" self._execute_analysis(event_data, self.module1.analyze) def _handle_get_results(self, event_data: Dict[str, Any]) -> Dict[str, Any]: """处理获取结果请求""" return self._process_results_request(event_data) def _execute_analysis(self, event_data, analyzer_func): """通用分析执行函数""" if not isinstance(event_data, dict): logger.error("无效的事件数据格式") return token = event_data.get('token') params = event_data.get('params', {}) logger.info(f"收到运行分析请求,token: {token}, 参数: {params}") try: front_nums = self._parse_numbers(self.front_var.get()) back_nums = self._parse_numbers(self.back_var.get()) data = { 'front_numbers': front_nums, 'back_numbers': back_nums, 'config': self._get_ui_config_values() } analysis_result = analyzer_func(data=data) self._send_result_to_ui(token, analysis_result) if self.app.event_center: self.app.event_center.publish( event_type="analysis_completed", data={ 'token': token, 'result': analysis_result, 'timestamp': datetime.datetime.now().isoformat() } ) except Exception as e: error_msg = f"分析过程中出错: {str(e)}" logger.error(error_msg) self._send_result_to_ui(token, {"error": error_msg}) def _parse_numbers(self, number_str: str) -> list: """解析数字字符串""" return [int(x) for x in number_str.split(",") if x.strip()] def _process_results_request(self, event_data: Dict[str, Any]) -> Dict[str, Any]: """处理获取结果请求""" if not isinstance(event_data, dict): logger.error("无效的事件数据格式") return {"error": "无效的事件数据格式"} token = event_data.get('token') logger.info(f"收到获取结果请求,token: {token}") try: result = {"status": "success", "data": "示例结果数据"} self._send_result_to_ui(token, result) return result except Exception as e: error_msg = f"获取结果过程中出错: {str(e)}" logger.error(error_msg) self._send_result_to_ui(token, {"error": error_msg}) return {"error": error_msg} def _send_result_to_ui(self, token: str, result: Dict[str, Any]) -> None: """将结果发送到指定token的UI位置""" if not token: logger.warning("未提供token,无法定位UI位置") return logger.info(f"准备将结果发送到token: {token}") if self.app.event_center: self.app.event_center.publish( event_type="update_ui", data={ 'token': token, 'result': result, 'timestamp': datetime.datetime.now().isoformat() } ) self._handle_analysis_result(result) def _get_ui_config_values(self) -> Dict[str, str]: """获取UI配置值""" config_values = {} for _, var_name, _ in GlobalConfig.UI_CONFIG: if hasattr(self, f"{var_name}_var"): config_values[var_name] = getattr(self, f"{var_name}_var").get() return config_values def _init_ui_variables(self): """初始化UI变量""" self.front_var = tk.StringVar() self.back_var = tk.StringVar() self.trend_var = tk.StringVar() for _, var_name, _ in GlobalConfig.UI_CONFIG: if not hasattr(self, f"{var_name}_var"): setattr(self, f"{var_name}_var", tk.StringVar()) def _setup_ui(self): """设置主界面UI""" title_label = tk.Label( self.main_frame, text=GlobalConfig.VERSION, font=("Arial", 16, "bold") ) title_label.pack(pady=10) # 创建配置项UI for label_text, var_name, _ in GlobalConfig.UI_CONFIG: frame = tk.Frame(self.module_content_frame) frame.pack(fill=tk.X, padx=10, pady=5) tk.Label(frame, text=label_text, width=15, anchor='w').pack(side=tk.LEFT) entry = tk.Entry( frame, textvariable=getattr(self, f"{var_name}_var"), width=25 ) entry.pack(side=tk.LEFT, padx=5) # 创建按钮 self._create_action_buttons() def _create_action_buttons(self): """创建操作按钮""" button_frame = tk.Frame(self.main_frame) button_frame.pack(fill=tk.X, padx=10, pady=10) tk.Button( button_frame, text="开始分析", command=self._start_analysis ).pack(side=tk.LEFT, padx=5) tk.Button( button_frame, text="保存配置", command=self._save_config ).pack(side=tk.LEFT, padx=5) def _start_analysis(self): """处理分析按钮点击""" self._execute_analysis( {'token': 'manual_analysis'}, self.module1.analyze ) def _save_config(self): """保存当前配置""" try: config_data = self._get_ui_config_values() save_path = GlobalConfig.CONFIG_PATHS.get('MODULE1_SAVE', 'module1_config.json') Path(save_path).parent.mkdir(parents=True, exist_ok=True) with open(save_path, 'w', encoding='utf-8') as f: json.dump(config_data, f, ensure_ascii=False, indent=2) logger.info(f"配置已保存到: {save_path}") if self.app.event_center: self.app.event_center.publish( event_type="config_saved", data={ 'module': GlobalConfig.MODULE1_ID, 'path': save_path, 'timestamp': datetime.datetime.now().isoformat() } ) except Exception as e: logger.error(f"保存配置失败: {e}") if self.app.event_center: self.app.event_center.publish( event_type="config_error", data={ 'module': GlobalConfig.MODULE1_ID, 'error': str(e), 'timestamp': datetime.datetime.now().isoformat() } ) def _handle_analysis_result(self, result_data: dict): """处理分析结果""" logger.info(f"收到分析结果: {result_data}") if "front" in result_data: self.front_var.set(",".join(map(str, result_data["front"]))) if "back" in result_data: self.back_var.set(",".join(map(str, result_data["back"]))) # 更新动态内容中的推荐数据 if 'recommendations' in result_data: self._dynamic_content['recommendations'] = result_data['recommendations'] self._update_pool_with_recommendations() if self.app.event_center: self.app.event_center.publish( event_type="ui_updated", data={ 'module': GlobalConfig.MODULE1_ID, 'updated_vars': ['front', 'back'], 'timestamp': datetime.datetime.now().isoformat() } ) def main(): """主函数入口""" root_window = tk.Tk() root_window.title("大乐透智能分析平台") root_window.geometry("1000x700+100+100") # 初始化事件中心 event_center = EventCenter() # 初始化号码池 number_pool = NumberPool( front_range=(1, 35), back_range=(1, 12), event_center=event_center ) # 创建主界面 MainInterface(root_window, number_pool) # 运行主循环 root_window.mainloop() if __name__ == "__main__": main() class MainInterface: def __init__(self, root: tk.Tk, pool: 'NumberPool'): # ... [其他初始化代码] ... # 添加缺失的初始化 self.DEBUG_MODE = False # 添加DEBUG_MODE属性 self._init_ui_components() # 初始化UI组件 self._init_modules() # 初始化模块系统 self._init_default_dynamic_content() # 初始化动态内容 # ... [其他初始化代码] ... def _init_ui_components(self): """初始化UI组件""" self._setup_main_window() self._setup_left_panel() self._setup_center_area() self._setup_right_panel() logger.info("UI组件初始化完成") def _init_modules(self): """初始化模块系统""" self.modules = { GlobalConfig.MODULE1_ID: InputAnalysisModule(), GlobalConfig.MODULE2_ID: CombinationAnalysisModule(), GlobalConfig.MODULE3_ID: FollowAnalysisModule(), GlobalConfig.MODULE4_ID: TrendAnalysisModule(), GlobalConfig.MODULE5_ID: NumberGenerationModule() } logger.info("模块系统初始化完成") def _init_default_dynamic_content(self): """初始化默认动态区内容""" if hasattr(self, 'module_content_frame'): Label(self.module_content_frame, text="请从左侧选择分析模块", font=('微软雅黑', 12)).pack(expand=True, pady=50) def save_module_state(self, module_id: str): """保存模块状态(示例实现)""" state_file = f"module_{module_id}_state.json" with open(state_file, 'w') as f: json.dump({"last_used": time.time()}, f) logger.info(f"模块状态已保存: {module_id}") def restore_module_state(self, module_id: str): """恢复模块状态(示例实现)""" state_file = f"module_{module_id}_state.json" if os.path.exists(state_file): with open(state_file, 'r') as f: state = json.load(f) logger.info(f"恢复模块状态: {module_id} - {state}") def _update_pool_with_recommendations(self, front: str, back: str): """使用推荐号码更新号码池""" self.pool.update("前区:", front.split()) self.pool.update("后区:", back.split()) logger.info(f"号码池已更新: 前区={front}, 后区={back}") # 修复文件操作类型错误 def _save_module_data(self, module: str): try: # ... [其他代码] ... # 确保目录存在 os.makedirs(os.path.dirname(filename), exist_ok=True) # 使用正确的文件打开方式 with open(filename, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) # ... [其他代码] ... # 移除重复声明的方法(只保留一个实现) # 保留以下方法实现: def _create_input_analysis_content(self, parent: Frame): # 具体实现... def _create_combination_analysis_content(self, parent: Frame): # 具体实现... # 移除其他重复声明 # 初始化未解析的UI组件 def _create_follow_analysis_content(self, parent: Frame): # ... [具体实现] ... # 初始化缺失的UI组件引用 self.front_recommend_more = StringVar() self.front_recommend_less = StringVar() self.back_recommend_more = StringVar() self.back_recommend_less = StringVar() # ... [其他代码] ... def _create_trend_analysis_content(self, parent: Frame): # ... [具体实现] ... # 初始化缺失的UI组件引用 self.hezhi_entry = Entry() self.zhihebi_entry = Entry() # 初始化其他缺失的entry... # ... [其他代码] ...
最新发布
08-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值