Как я могу исправить эту ошибку, что ошибка Tkinter: не удается удалить команду Tcl? - PullRequest
0 голосов
/ 30 марта 2020

У меня проблема с командой Tkinter Tcl. когда GUI windows закрывается, возвращается ошибка, из-за которой невозможно удалить команду TCL. Я создал текст секундомера в tk.Label. если таймер не запускается, все в порядке, я не получаю никаких ошибок. Но останавливаю ли я таймер или сбрасываю его после запуска таймера, я получаю эту ошибку при закрытии экрана. tk.Label уничтожена на GUI, и окно не закрывается.

Моя версия tkinter - 8,6, а Python3 версия - 3,6,9

Вот код:

import tkinter as tk 
import time
from PIL import Image, ImageTk
#TODO - read this, create new one Button, Labels or something like that. You mustn't use self.master, self in first arguments

class GUISHOW(tk.Frame):
    def __init__(self, master=None):
        # inherit class 
        super().__init__(master)
        self.master = master
        # self command
        # print(dir(self.master))
        #print(self.master._tclCommands)
        tkError, commands, number = self.master._tclCommands
        self.master.bind(commands, self.callback)
        print(tkError)
        self.master.title("ReadingTime")
        self.master.geometry("500x500")
        self.master.resizable(0,0)
        # time configuration
        self.timerstr = tk.StringVar()
        self.elapsedTime = 0.0
        self.start = 0.0
        # this use boolean for reset,start,pause button
        self.running = False 

        # init gui and shows

        self.make_gui()
        self.master.mainloop()

    def callback(self):
        print("there is the function", self.x)

    # timer callback method with trace
    def trace_callback_method(self, *args):
        print("get the values here", self.timerstr.get())

######################################################
# create graphic ui with widget
######################################################
    def make_gui(self): 
        self.create_timer()
        self.start_time()
        self.reset_time()
        self.stop_time()
######################################################
# create time 
######################################################
    def set_time(self, elap_time):
        minutes = int(elap_time/60)
        seconds = int (elap_time - minutes *60.0)
        hseconds = int((elap_time -minutes *60.0 - seconds)*100)
        self.timerstr.trace("w", self.trace_callback_method)
        self.timerstr.set('%02d:%02d:%02d' % (minutes,seconds,hseconds))

######################################################
# create timer and shows gui
######################################################
    def create_timer(self):
        self.label = tk.Label(textvariable=self.timerstr)
        self.set_time(self.elapsedTime)
        self.label.grid(row=0, column=3, sticky=tk.W)
######################################################
# update time 
    def update(self):
        self.elapsedTime = time.time() - self.start
        self.set_time(self.elapsedTime)
        self._timer = self.label.after(50,self.update)

######################################################
# start time
    def handler_start_time(self):
        # time start with boolean for second start will not be running
        print(" Start time")
        if not self.running: 
            self.start = time.time() - self.elapsedTime
            self.update()
            self.running = True 


    def start_time(self):
        # start icon 
        # TODO - the image does not shows in button - FIXIT
        """
        image =Image.open("icon/start.png")
        image = image.resize((24,24))
        start_icon_image =  ImageTk.PhotoImage(image) 
        #start_icon_image = start_icon.subsample(3,3)
        """
        self.play = tk.Button(text="Start",compound=tk.LEFT, \
                command=lambda:self.handler_start_time()).grid(row=1,column=0,sticky=tk.W)
######################################################
# pause time
    def handler_reset_time(self):
        # time start with boolean for second start will not be running
        print(" Reset time")
        self.start = time.time()
        self.elapsedTime = 0.0
        self.set_time(self.elapsedTime)
    def reset_time(self):
        self.reset = tk.Button(text="Reset", command=lambda: self.handler_reset_time()).grid(row=1,column=1,sticky=tk.W)
######################################################
# stop time
    def handler_stop_time(self):
        # time start with boolean for second start will not be running
        print(" Stop time")
        if self.running: 
            # self._timer is value in update() function that stop the timer
            self.master.after_cancel(self._timer)
            self.elapsedTime = time.time() - self.start
            self.set_time(self.elapsedTime)
            self.running = False


    def stop_time(self):
        self.stop = tk.Button(text="Stop", command=lambda: self.handler_stop_time()).grid(row=1,column=2,sticky=tk.W)

И я вызываю класс в главной функции

import tkinter as tk
from helper.gui_shows import GUISHOW
# init class
gui = tk.Tk()

# main function
if __name__ == "__main__": 
    print("Program is started")
    # gui init
    app = GUISHOW(gui)

1 Ответ

3 голосов
/ 30 марта 2020

Измените это

 string_name = self.timerstr.trace_variable

на это

string_name = self.timerstr.trace_variable('r',self.handler_stop_time)

Поскольку вы на самом деле не вызываете функцию

А также для исправления TclError измените это

self._timer = self.label.after(50,self.update)

к этому

self._timer = self.master.after(50,self.update)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...