【问题标题】:Python 3.3 and TKinter, error message and crashPython 3.3 和 TKinter,错误消息和崩溃
【发布时间】:2016-02-06 20:20:22
【问题描述】:

作为一种爱好,我喜欢涉足这种 Python 的东西。我正在尝试制作一个简单的程序,帮助我心爱的妻子跟踪和识别食物敏感性。我已经有了这个的工作版本,但出于无聊,我试图通过在主屏幕上添加一个小部件来改进它。这样做后,我发现了一个我无法弄清楚的错误。我什至不确定它想诚实地告诉我什么。但每当我点击主菜单中的“下一步”按钮时,它就会发生。

我的代码:

from tkinter import *
import os, shelve


class Food:

    def __init__(self, name, score):
        self.name = name
        self.score = score


class Main:

    def __init__(self, master):
        self.master = master
        self.master_frame = Frame(self.master)
        self.master_frame.pack()
        self.home_frame()

    def home_frame(self):
        for child in self.master_frame.winfo_children():
            child.destroy()    
        self.ticker = ' ' * 29
        self.start = 0
        self.end = 29
        for i in catalog.values():
            self.ticker = self.ticker + str(i.name) + ': ' + str(i.score) + '%' + ' ' * 10
        print(self.ticker)
        self.create_widgets()

    def create_widgets(self):

        self.ticker_frame = Frame(self.master_frame, bd = 5, bg = 'black')
        self.ticker_label = Label(self.ticker_frame, text = '<empty>', fg = 'white', bg = 'black')
        self.ticker_label.grid(row = 0, columnspan = 3, sticky = E + W)
        self.ticker_frame.pack(expand = 1, fill = 'x', anchor = 'center')

        self.button_frame = Frame(self.master_frame, bd = 5, bg = 'black')
        Button(self.button_frame, text = 'Next', width = 10, command = self.next_win).grid(row = 0, column = 0)
        Button(self.button_frame, text = 'N/A', width = 10, command = self.master.destroy).grid(row = 0, column = 1)
        Button(self.button_frame, text = 'Exit', width = 10, command = self.master.destroy).grid(row = 0, column = 2)
        self.button_frame.pack()

        self.run_ticker()

    def run_ticker(self):
        ticker_text = self.ticker[self.start:self.end]
        self.ticker_label.config(text = ticker_text, font = ('courier', 10, 'bold'))
        self.start += 1
        self.end += 1
        if self.start == len(self.ticker):
            self.start = 0
            self.end = 29
        self.master.after(250, self.run_ticker)

    def next_win(self):
        for child in self.master_frame.winfo_children():
            child.destroy()
        self.next_frame = Frame(self.master_frame)
        new_label = Label(self.next_frame, text = 'Blah...').grid()
        Button(self.next_frame, text = 'Main', command = self.home_frame).grid()
        self.next_frame.pack()




x = Food('Grapes', 50)
y = Food('Cheese', 75)
z = Food('Eggs', 35)

catalog = {}

catalog[x.name] = x
catalog[y.name] = y
catalog[z.name] = z



root = Tk()
Main(root)

root.mainloop()

我得到的错误消息,对于任何一个按钮都是一样的:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
    return self.func(*args)
  File "C:\Python33\lib\tkinter\__init__.py", line 501, in callit
    func(*args)
  File "C:\Users\Gregory\Desktop\Test2 Working except ticker.pyw", line 111, in run_ticker
    self.ticker_label.config(text = ticker_text, font = ('courier', 10, 'bold'))
  File "C:\Python33\lib\tkinter\__init__.py", line 1230, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Python33\lib\tkinter\__init__.py", line 1221, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".52922632.52924032"

先生。奥克利在回答我之前的一个问题时说得很有说服力,“除非你知道引擎盖下发生了什么......”而我显然不知道,这就是为什么我不知道外壳试图告诉什么我。

还有一个不太重要的问题: 我试图将程序的主菜单保留在屏幕的右上角。我的尝试失败了。它从右上角初始化,然后在打开一个新窗口时正确移动,最后在返回主菜单时,它落入正确的位置。显然我在这里也遗漏了一些东西。

一如既往的感谢!

【问题讨论】:

  • 这只是太多的代码。我不认为所有这些都是相关的。请缩小范围,使其成为minimal reproducible example
  • 另外,大多数情况下发生错误是因为没有父窗口可以执行该命令。您要么销毁它,要么在创建它之前运行该命令。
  • 抱歉,我发布了整个内容,因为我不知道从哪里开始找到问题所在。我将尝试用较小的样本重新创建问题并稍作编辑。我也会看看你提到的父母问题。感谢您的宝贵时间。

标签: tkinter python-3.3


【解决方案1】:

你有一个破坏

def next_win(self):
    for child in self.master_frame.winfo_children():
        child.destroy()

其中包含ticker_frame及其所有小部件,因此run_ticker()中的after语句在框架被销毁后仍在调用该函数。创建框架时使用 self.is_tinker_frame = True 之类的变量,并在销毁框架时将其设置为 False 加:

if self.is_tkinter_frame:
    self.master.after(250, self.run_ticker)

此外,在变量设置为 False 后等待超过 250 年,以销毁框架,以允许任何调用完成。

【讨论】:

  • 为了确保我理解正确,我已经销毁了小部件,但没有停止代码。股票代码试图继续,导致错误。我没有想到。太棒了,谢谢你!我会尝试按照您的建议添加布尔值。关于我遇到的 .geometry 窗口放置问题有什么想法吗?
  • 修复这个问题,并用简单的代码说明几何问题。
  • 用您提供的解决方案解决了问题。谢谢!
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 2013-06-22
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
相关资源
最近更新 更多