Python, Tkinter: how can I prevent tlinter gui mainloop from crashing with streaming

Hi, I have a small gui python interface with two buttons, start (which starts the counter) and stops (this means you need to stop the counter), the counter is an infinite loop, since I don't want it to end, the second button is pressed . The problem is that the second button cannot be pressed while the function from the first is still running. I read that I need to use threads, and I tried, but I don’t quite understand how I can do this. Please, help.

from Tkinter import *
import threading


class Threader(threading.Thread):
    def run(self):
        for _ in range(10):
            print threading.current_thread().getName()

    def main(self):
        import itertools
        for i in itertools.count(1, 1):
            print i

    def other(self):
        print "Other"

m = Threader(name="main")
o = Threader(name="other")

try:
    '''From here on we are building the Gui'''
    root = Tk()

    '''Lets build the GUI'''
    '''We need two frames to help sort shit, a left and a right vertical frame'''
    leftFrame = Frame(root)
    leftFrame.pack(side=LEFT)
    rightFrame = Frame(root)
    rightFrame.pack(side=RIGHT)
    '''Widgets'''
    '''Buttons'''
    playButton = Button(leftFrame, text="Play", fg="blue", command=m.main)
    stopButton = Button(rightFrame, text="Stop", fg="red", command=o.other)
    playButton.pack(side=TOP)
    stopButton.pack(side=BOTTOM)

    root.mainloop()
except Exception, e:
    print e
+2
source share
2 answers

threading. other, , itertools . , .

:

threading.Thread Threader, .

, , run, start() . start() run.

, , tkinter - . , , - , , . . Python -, GIL, ( ), - . , GIL "" , . multiprocessing.

self.daemon = True. , ( TK GUI)

from tkinter import *
import threading, time

class Threader(threading.Thread):

    def __init__(self, *args, **kwargs):

        threading.Thread.__init__(self, *args, **kwargs)
        self.daemon = True
        self.start()

    def run(self):

         while True:
            print("Look a while true loop that doesn't block the GUI!")
            print("Current Thread: %s" % self.name)
            time.sleep(1)

if __name__ == '__main__':

    root = Tk()
    leftFrame = Frame(root)
    leftFrame.pack(side=LEFT)
    rightFrame = Frame(root)
    rightFrame.pack(side=RIGHT)
    playButton = Button(leftFrame, text="Play", fg="blue", 
        command= lambda: Threader(name='Play-Thread'))
    stopButton = Button(rightFrame, text="Stop", fg="red", 
        command= lambda: Threader(name='Stop-Thread'))
    playButton.pack(side=TOP)
    stopButton.pack(side=BOTTOM)
    root.mainloop()
+3

- , , Tkinter after() . .

class TimerTest():
    def __init__(self, root):
        self.root=root

        Button(root, text="Play", fg="blue",
                            command=self.startit).grid(row=1, column=0)
        Button(root, text="Stop", fg="red",
                            command=self.stopit).grid(row=1, column=1)

        self.is_running=True
        self.count=IntVar()
        Label(root, textvariable=self.count,
              bg="lightblue").grid(row=0, column=0, columnspan=2, sticky="ew")

    def startit(self):
        self.is_running=True
        self.increment_counter()

    def increment_counter(self):
        if self.is_running:
             c=self.count.get()
             c += 1
             self.count.set(c)
             root.after(1000, self.increment_counter)  ## every second

    def stopit(self):
        self.is_running = False

root = Tk()
TT=TimerTest(root)
root.mainloop()
0

Source: https://habr.com/ru/post/1683344/


All Articles