Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
615 views
in Technique[技术] by (71.8m points)

python - Multi threading in Tkinter GUI, threads in different classes

I'm currently learning the Tkinter GUI programming. And I'm stuck in somewhere in multi threading concept. Even though this topic is discussed several times here, I couldn't catch the concept and apply it to my small sample program.

Below is my code:

from PIL import Image, ImageTk 
from Tkinter import Tk, Label, BOTH
from ttk import Frame, Style
from Tkinter import *
import time


class Widgets(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.grid()
        self.parent = parent
        self.initUI(parent)

    def initUI(self, parent):
        self.parent.title("Count Numbers")

        for r in range(10):
            self.parent.rowconfigure(r, weight=1)    
        for c in range(10):
            self.parent.columnconfigure(c, weight=1)        

        self.button1 = Button(parent, text = "count")
        self.button1.grid(row = 1, column = 1, rowspan = 1, columnspan = 2, sticky = W+E+N+S )
        self.button1["command"] = self.countNum

        self.button2 = Button(parent, text = "say Hello")
        self.button2.grid(row = 1, column = 7, rowspan = 1, columnspan = 2, sticky = W+E+N+S) 
        self.button2["command"] = PrintHello(self).helloPrint

    def countNum(self):
        for i in range(10):
            print i
            time.sleep(2)   

class PrintHello(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.grid()
        self.parent = parent

    def helloPrint(self):
        print "Hello"

def main():
    root = Tk()
    root.geometry("300x200")
    app = Widgets(root)
    root.mainloop()

if __name__ == '__main__':
    main() 

enter image description here

The output is a GUI with 2 buttons- first one prints the numbers and second prints "Hello". But on clicking the first button, the GUI gets frozen while the numbers are getting printed. And while searching for a solution, I found that 'multi threading' may help. But after several attempts, I couldn't apply multi-threading to my sample program given.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You don't need threading for something this simple.

The GUI is freezing because you're putting a time.sleep inside the function which is blocking the main thread until it's finished.

Simply use Tk's built in after method. Change your function to.

def countNum(self, num=0):
    if num < 10:
        print num
        root.after(2000, lambda: self.countNum(num + 1))
    else:
        print "Stopping after call"

The after method takes the following arguments:

after(delay_ms, callback, arguments)

The time is in milliseconds, and 1000 ms = 1 second. So, we pass 2,000 ms for a 2 second delay.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...