You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python+Tkinter+SQL:如何在两个Frame之间传递变量?

CRM搜索结果跨Frame传递解决方案

不用全局变量的前提下,推荐通过父组件协调+回调函数的方式实现,核心思路是让负责搜索的Frame不直接依赖结果展示Frame,而是通过父容器传递的回调函数把结果交出去,由父容器通知结果Frame更新。

实现示例(基于Tkinter)

import tkinter as tk
import sqlite3

class SearchFrame(tk.Frame):
    def __init__(self, parent, search_callback, **kwargs):
        super().__init__(parent, **kwargs)
        # 接收父容器传递的回调函数
        self.search_callback = search_callback
        
        # 搜索输入框和按钮
        self.query_input = tk.Entry(self, width=30)
        self.query_input.pack(padx=8, pady=8, side=tk.LEFT)
        
        tk.Button(self, text="搜索", command=self.run_search).pack(padx=8, pady=8, side=tk.LEFT)
    
    def run_search(self):
        query_keyword = self.query_input.get().strip()
        if not query_keyword:
            return
        
        # 执行SQL查询(注意用参数化查询防注入)
        conn = sqlite3.connect("crm_database.db")
        cursor = conn.cursor()
        # 参数化查询避免SQL注入
        cursor.execute(
            "SELECT id, name, phone, email FROM customers WHERE name LIKE ? OR phone LIKE ?",
            (f"%{query_keyword}%", f"%{query_keyword}%")
        )
        search_results = cursor.fetchall()
        conn.close()
        
        # 通过回调把结果传给父容器
        self.search_callback(search_results)

class ResultsFrame(tk.Frame):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)
        # 结果展示列表框
        self.result_list = tk.Listbox(self, width=80, height=20)
        self.result_list.pack(fill=tk.BOTH, expand=True, padx=8, pady=8)
    
    def refresh_results(self, results):
        # 清空原有内容并加载新结果
        self.result_list.delete(0, tk.END)
        if not results:
            self.result_list.insert(tk.END, "未找到匹配的记录")
            return
        # 格式化展示每条结果
        for idx, record in enumerate(results, 1):
            self.result_list.insert(tk.END, f"{idx}. ID:{record[0]} | 姓名:{record[1]} | 电话:{record[2]} | 邮箱:{record[3]}")

class CRMApplication(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("简易CRM系统")
        
        # 初始化搜索和结果Frame
        self.search_panel = SearchFrame(self, search_callback=self.update_results_panel)
        self.search_panel.pack(fill=tk.X, padx=5, pady=5)
        
        self.results_panel = ResultsFrame(self)
        self.results_panel.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
    
    def update_results_panel(self, results):
        # 父容器中转结果,调用结果Frame的更新方法
        self.results_panel.refresh_results(results)

if __name__ == "__main__":
    app = CRMApplication()
    app.mainloop()

关键说明

  1. 解耦设计:SearchFrame只负责接收用户输入、执行查询,不需要知道ResultsFrame的存在,完全通过回调传递数据,降低模块间依赖。
  2. 避免全局变量:所有数据传递通过父容器的方法中转,没有使用全局变量。
  3. SQL注入防护:示例中使用了参数化查询,不要直接拼接SQL字符串,避免安全风险。

备选方案:自定义事件机制

如果偏好事件驱动的方式,也可以用Tkinter的自定义事件实现:

  • 在SearchFrame查询完成后,通过self.parent.event_generate("<<SearchCompleted>>", data=results)触发自定义事件。
  • 在ResultsFrame的初始化方法中绑定事件:self.parent.bind("<<SearchCompleted>>", self.handle_results),然后实现handle_results方法接收数据并更新界面。

内容的提问来源于stack exchange,提问作者LearnedStudent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:42:40