0

I am trying to make a status light on my tkinter GUI. At this point I just want it to rotate from green to red to show that the script hasn't frozen. The python traceback errors that I get all point to __libraries that I don't understand. I feel like this must be a namespace problem, but I'm ripping out my hair trying to put my finger on it.

The eventCheck() method worked great at creating a label that toggled between 0 and 1 before I created the canvas object and tried passing c into it. There is so little information out there on what I am trying to do, maybe there is a better way?

Here is a condensed version of my script:

import tkinter as tk
from tkinter import Canvas
import time
import threading

class myGUI(tk.Frame):

    def __init__(self, master, event):
        self.master = master
        self.event = event
        super().__init__(master)

        self.label = tk.Label(self, text="")
        self.label.grid()
        self.after(1, self.eventCheck)

        c = tk.Canvas(self, bg='white', width=80, height=80)
        c.grid()
        self.eventCheck(c)

    def redCircle(self, c):
        c.create_oval(20, 20, 80, 80, width=0, fill='red')
        print("redCircle Called")

    def greenCircle(self,c):
        c.create_oval(20, 20, 80, 80, width=0, fill='green')
        print("greenCircle Called")

    def eventCheck(self, c):
        self.label['text'] = self.event.is_set()
        if self.label['text'] == 0:
            self.redCircle(c)
        else:
            self.greenCircle(c)
        self.after(2000, self.eventCheck(c))

def timingLoop(event):
    while True:
        event.set()
        time.sleep(2)
        event.clear()
        time.sleep(2)

def main():
    root = tk.Tk()
    root.title("myFirst GUI")
    event = threading.Event()
    t=threading.Thread(target=timingLoop, args=(event,))
    t.daemon = True
    t.start()
    app = myGUI(root, event)
    root.mainloop()

if __name__=="__main__":
    main()

1 Answer 1

1

I found two major issues with your code. First, this isn't doing what you think it should:

def eventCheck(self, c):
        # ...
        self.after(2000, self.eventCheck(c))

Because you passed the result of a call to self.eventCheck(c) to after() instead of the method self.eventCheck, this is an infinite recursion that takes place immediately.

The second issue is that if you comment out all your timing and event stuff, your interface never actually comes up, so there's never anything to see. I've condensed (simplified) your example script even further into one that basically works:

import tkinter as tk
import threading
import time

class myGUI:

    def __init__(self, master, event):
        self.master = master
        self.event = event

        self.label = tk.Label(master, text="")
        self.label.pack()

        self.canvas = tk.Canvas(master, bg='white', width=80, height=80)
        self.canvas.pack()

        self.eventCheck()

    def redCircle(self):
        self.canvas.create_oval(20, 20, 80, 80, width=0, fill='red')
        print("redCircle Called")

    def greenCircle(self):
        self.canvas.create_oval(20, 20, 80, 80, width=0, fill='green')
        print("greenCircle Called")

    def eventCheck(self):
        flag = self.event.is_set()

        self.label['text'] = flag

        if flag:
            self.greenCircle()
        else:
            self.redCircle()

        self.master.after(2000, self.eventCheck)

def timingLoop(event):
    while True:
        event.set()
        time.sleep(2)
        event.clear()
        time.sleep(2)

def main():
    root = tk.Tk()
    root.title("myFirst GUI")

    event = threading.Event()
    t = threading.Thread(target=timingLoop, args=(event,))
    t.daemon = True
    t.start()

    app = myGUI(root, event)
    root.mainloop()

if __name__ == "__main__":
    main()

enter image description here

Now you should be able to add back your Frame superclass. Make sure to add the frame that is myGUI to your root object.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. That was a tremendous help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.