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

如何在Tkinter画布绘制网格并录入数据,开发独立统计程序?

一步步实现你的Tkinter统计工具需求

我帮你梳理并修改代码,解决画布数据录入、统计计算整合的问题,同时给你后续扩展和打包的方案:

一、核心修改:画布上创建2x2数据录入表格

咱们把原来控制台输入的逻辑改成GUI交互形式,在画布上画出网格+输入框,用户直接在窗口里录入A/B/C/D四个单元格的数据,不用再切换到控制台。

二、整合统计计算与结果展示

把Fisher精确检验的逻辑移到Window类里,这样可以直接获取输入框的数据,计算后在画布上显示结果,不用依赖控制台打印。

三、修改后的完整代码

import tkinter as tk
import math

class Window(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.main_window()
        self.widgets()
        self.create_data_canvas()

    # 主窗口基础配置
    def main_window(self):
        self.master.title("Quick-Statistics Calculator")
        self.master.geometry("1000x800")
        self.pack(fill=tk.BOTH, expand=True)

    # 菜单栏创建
    def widgets(self):
        main_menu = tk.Menu(self.master, tearoff=0)
        self.master.config(menu=main_menu)

        # 文件菜单
        file = tk.Menu(main_menu, tearoff=0)
        file.add_command(label="Save")
        file.add_separator()
        file.add_command(label="Exit", command=self.master.quit)
        main_menu.add_cascade(label="File", menu=file)

        # 编辑菜单
        edit = tk.Menu(main_menu, tearoff=0)
        edit.add_command(label="Undo")
        main_menu.add_cascade(label="Edit", menu=edit)

        # 均值分析菜单
        means = tk.Menu(main_menu, tearoff=0)
        means.add_command(label="Group t")
        means.add_command(label="Paired t")
        means.add_separator()
        means.add_command(label="ANOVA")
        means.add_separator()
        means.add_command(label="Mann-Whitney U")
        means.add_command(label="Wilcoxon rank sum")
        main_menu.add_cascade(label="Means", menu=means)

        # 卡方/表格分析菜单
        chi = tk.Menu(main_menu, tearoff=0)
        chi.add_command(label="Chi-Square 2x2 table")
        chi.add_command(label="Chi-Square for larger table")
        chi.add_separator()
        chi.add_command(label="McNemar's Test")
        chi.add_command(label="Fisher's Exact", command=self.calculate_fishers)
        main_menu.add_cascade(label="Tables", menu=chi)

        # 帮助菜单
        help_menu = tk.Menu(main_menu, tearoff=0)
        help_menu.add_command(label="Means Analysis")
        help_menu.add_command(label="Chi-Square Analysis")
        main_menu.add_cascade(label="Help", menu=help_menu)

    # 创建画布与数据录入网格
    def create_data_canvas(self):
        # 创建画布并铺满窗口
        self.canvas = tk.Canvas(self, bg="white")
        self.canvas.pack(fill=tk.BOTH, expand=True)

        # 绘制2x2数据网格
        grid_size = 150
        start_x, start_y = 200, 100
        # 绘制横线
        for y_offset in [0, grid_size, 2*grid_size]:
            self.canvas.create_line(start_x, start_y + y_offset, start_x + 2*grid_size, start_y + y_offset)
        # 绘制竖线
        for x_offset in [0, grid_size, 2*grid_size]:
            self.canvas.create_line(start_x + x_offset, start_y, start_x + x_offset, start_y + 2*grid_size)

        # 添加单元格标签
        labels = [("Cell A", start_x+grid_size//2, start_y+grid_size//2),
                  ("Cell B", start_x+grid_size+grid_size//2, start_y+grid_size//2),
                  ("Cell C", start_x+grid_size//2, start_y+grid_size+grid_size//2),
                  ("Cell D", start_x+grid_size+grid_size//2, start_y+grid_size+grid_size//2)]
        for text, x, y in labels:
            self.canvas.create_text(x, y - 30, fill="darkblue", font="Times 14 bold", text=text)

        # 创建输入框并嵌入画布
        self.entries = {}
        entry_positions = [("A", start_x+20, start_y+20),
                           ("B", start_x+grid_size+20, start_y+20),
                           ("C", start_x+20, start_y+grid_size+20),
                           ("D", start_x+grid_size+20, start_y+grid_size+20)]
        for cell, x, y in entry_positions:
            entry = tk.Entry(self.canvas, font="Times 16", width=8)
            self.canvas.create_window(x, y, window=entry, anchor=tk.NW)
            self.entries[cell] = entry

        # 添加提示文字
        self.canvas.create_text(500, 50, fill="darkblue", font="Times 20 italic bold", text="Enter 2x2 Table Data Below")

        # 结果显示区域
        self.result_text = self.canvas.create_text(500, 400, fill="darkred", font="Times 18 bold", text="")

    # Fisher精确检验计算逻辑
    def calculate_fishers(self):
        try:
            # 获取输入框数据并转换为数值
            cell_a = float(self.entries["A"].get())
            cell_b = float(self.entries["B"].get())
            cell_c = float(self.entries["C"].get())
            cell_d = float(self.entries["D"].get())

            # 计算Fisher精确检验值(注意阶乘只接受整数,先转int)
            fenum = math.factorial(int(cell_a+cell_b)) * math.factorial(int(cell_c+cell_d)) * \
                    math.factorial(int(cell_a+cell_c)) * math.factorial(int(cell_b+cell_d))
            feden = math.factorial(int(cell_a)) * math.factorial(int(cell_b)) * \
                    math.factorial(int(cell_c)) * math.factorial(int(cell_d)) * \
                    math.factorial(int(cell_a+cell_b+cell_c+cell_d))
            fe = fenum / feden

            # 在画布上更新结果
            self.canvas.itemconfig(self.result_text, text=f"Fisher's Exact Result: {fe:.4f}")
        except ValueError:
            # 处理非数字输入的错误提示
            self.canvas.itemconfig(self.result_text, text="Error: Please enter valid numbers!")
        except math.DomainError:
            # 处理负数阶乘的错误提示
            self.canvas.itemconfig(self.result_text, text="Error: Values must be non-negative integers!")

if __name__ == "__main__":
    main = tk.Tk()
    comm_prog = Window(master=main)
    main.mainloop()

四、后续扩展:绘制正态分布

如果要在画布上绘制正态分布,可以结合Anaconda的numpy生成数据,用matplotlib嵌入Tkinter窗口:

  1. 安装依赖库:conda install matplotlib numpy
  2. 在代码中导入matplotlib.backends.backend_tkagg模块,创建专门的Frame放置绘图区域,生成正态分布数据后调用matplotlib绘制。

五、打包成独立程序

用Anaconda的pyinstaller打包成可执行文件:

  1. 安装pyinstaller:conda install pyinstaller
  2. 执行打包命令:pyinstaller --onefile --windowed your_script_name.py
    • --onefile:生成单个可执行文件
    • --windowed:去掉控制台窗口,适合GUI程序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:56:39