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

在Tkinter中如何将坐标追加到列表且避免被覆盖

视力测试APP坐标记录问题修复

问题描述

正在开发一款视力测试APP:用户注视屏幕中心注视点,每隔几秒出现并消失刺激物,测试持续1分钟。当刺激物显示时用户按下空格键,需记录该刺激物的坐标并追加到列表,最终根据按键情况展示用户视野范围。

当前问题:坐标追加到列表时不断被覆盖,仅能保留最后一个坐标。经排查,问题出在get_results()函数——每次调用该函数都会初始化self.accuracies为空列表,导致之前的记录被清空。

问题代码片段

def get_results(self, event):
        self.accuracies = []
        inaccuracies = []
        if len(self.canvas.coords(self.dot)) > 0:
            self.accuracies.append(self.canvas.coords(self.dot))
        print(self.accuracies)

def test_results_page(self):
        print(self.accuracies)
        self.destroy_widgets()
        canvas = Canvas(self.root, bg="white")
        canvas.place(relx=0, rely=0, relwidth=1, relheight=1)
        canvas.create_rectangle(self.accuracies[0][0], self.accuracies[0][1], self.accuracies[0][2], self.accuracies[0][3], outline="black", fill="black")

def draw_dot(self, x, y, color):
        self.dot = self.canvas.create_oval(x, y, x + 10, y + 10, outline=color, fill=color)
        self.root.bind("<space>", self.get_results)

修复方案

  1. 移除get_results()内的列表初始化
    删除self.accuracies = []这行代码,避免每次触发空格键都清空记录列表。
  2. 在类初始化方法中初始化self.accuracies
    确保列表仅在APP实例创建时初始化一次,示例:
    def __init__(self, root):
        self.root = root
        self.accuracies = []  # 仅初始化一次空列表
        # 其他初始化代码(如创建画布、设置注视点等)
    
  3. 修复结果页的坐标绘制逻辑
    当前代码仅绘制第一个记录的坐标,需遍历所有记录的坐标来完整展示视野范围:
    def test_results_page(self):
        print(self.accuracies)
        self.destroy_widgets()
        canvas = Canvas(self.root, bg="white")
        canvas.place(relx=0, rely=0, relwidth=1, relheight=1)
        # 遍历所有记录的坐标进行绘制
        for coords in self.accuracies:
            canvas.create_rectangle(coords[0], coords[1], coords[2], coords[3], outline="black", fill="black")
    
  4. 优化按键绑定逻辑
    避免每次绘制刺激物都重复绑定空格键,将绑定操作移至类初始化方法中,防止多次绑定导致重复触发:
    def __init__(self, root):
        self.root = root
        self.accuracies = []
        self.root.bind("<space>", self.get_results)  # 仅绑定一次空格键
        # 其他初始化代码
    
  5. 可选:添加坐标副本存储
    由于canvas.coords()返回的是引用,后续刺激物坐标变化可能影响已记录的列表,建议存储坐标的副本:
    self.accuracies.append(self.canvas.coords(self.dot).copy())
    

修正后的完整关键代码

class VisionTestApp:
    def __init__(self, root):
        self.root = root
        self.accuracies = []  # 初始化空记录列表
        self.root.bind("<space>", self.get_results)  # 单次绑定空格键
        # 初始化主画布
        self.canvas = Canvas(self.root, bg="white")
        self.canvas.place(relx=0, rely=0, relwidth=1, relheight=1)
        # 绘制中心注视点(示例)
        self.canvas.create_oval(490, 290, 510, 310, outline="red", fill="red")

    def get_results(self, event):
        # 移除清空列表的代码
        inaccuracies = []  # 若未使用可删除
        if len(self.canvas.coords(self.dot)) > 0:
            # 存储坐标副本,避免后续修改影响记录
            self.accuracies.append(self.canvas.coords(self.dot).copy())
        print(self.accuracies)

    def test_results_page(self):
        print(self.accuracies)
        self.destroy_widgets()
        canvas = Canvas(self.root, bg="white")
        canvas.place(relx=0, rely=0, relwidth=1, relheight=1)
        # 绘制所有记录的刺激物坐标
        for coords in self.accuracies:
            canvas.create_rectangle(coords[0], coords[1], coords[2], coords[3], outline="black", fill="black")

    def draw_dot(self, x, y, color):
        self.dot = self.canvas.create_oval(x, y, x + 10, y + 10, outline=color, fill="black")
        # 移除重复的空格键绑定代码

内容的提问来源于Stack Exchange,提问作者Mjturn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:43:04