Python - Tkinter窗口和无限循环类同时进行

时间:2013-12-30 01:31:35

标签: python multithreading loops tkinter

我遇到了一个问题,我想在Python的mainloop之后调用一些代码,这些代码是在一个类中编写的。但是这个类包含一个可能的无限循环,当我尝试在它之后调用mainloop()时会导致Tkinter冻结。是否有可能从第一类到窗口获取数据,即使它可能是无穷无尽的? 这是我目前的代码:

from tkinter import *
import re
import threading
import _thread as thread
from time import sleep

class interpret(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        print("some text")
        self.read()   
    def read(self):
        laenge = self.file_len(self.file)
        try:
            while self.line < laenge and not self.graceful:
                fp = open(self.file)
                for i, line in enumerate(fp):
                    if i == self.line:
                        content = line.rstrip().lower()
                        content = content.split(";", 1)[0]
                        content = self.replace(content)
                        #simply is getting some Info of the File, can change self.line
                        #it also could trigger an input(), which I want to replace by the canvas input
                        self.get_operator(content)
                self.line += 1
                fp.close()
        except KeyboardInterrupt:
            print("\n\n-----Info-----")
            for i in range(len(self.memory)):
                print(i,":",self.memory[i])
        except IndexError:
            print("Buffer Overflow in line",self.line+1)
class Window(threading.Thread):
    pointer = 40
    h= 500
    txt = []
    master = Tk()
    buffer_txt = []
    expect_input = True
    input_method = 1 #0=Nothing,1=Alphanumeric,2=Everything

    def __init__(self):
        threading.Thread.__init__(self)
        self.w = Canvas(self.master, width=500, height=self.h, background="black",highlightthickness=0)
        self.w.pack()
        self.master.bind("<Return>", self.send)
        self.master.bind("<Key>", self.to_buffer)
        self.w.update()
        mainloop() 
    def update(self):
        if self.txt != []:
            for i in range(len(self.txt)):
                self.w.coords(self.txt[i], 20, ((i*15)+30))
    def text_add(self,text):
        if(len(self.txt) > 30):
            self.txt = self.txt[1:]
            self.w.delete(self.txt[0])
            self.update()
        self.txt += [self.w.create_text(20, self.pointer, text=text, fill="white",anchor="w")]
        if self.pointer < 485:
            self.pointer += 15
        self.w.update()
    def to_buffer(self,event):
        if self.expect_input:
            if (((event.keycode >= 48 and event.keycode <= 57) or (event.keycode >= 65 and event.keycode <= 90) or (event.keycode >= 97 and event.keycode <= 122) or event.keycode == 8 or event.keycode == 32) and self.input_method == 1) or self.input_method == 2:
                print("My Mode:",self.input_method,"My keycode:",event.keycode)
                self.w.delete(self.txt[len(self.txt)-1])
                self.txt = self.txt[:len(self.txt)-1]
                print("Out:",str(event.keycode))
                s = str(event.char)
                if event.keycode == 8 and len(self.buffer_txt) > 0:
                    del self.buffer_txt[-1]
                else:
                    self.buffer_txt += [s]
                t = "".join(self.buffer_txt)
                self.txt += [self.w.create_text(20, self.pointer, text=t, fill="white",anchor="w")]
                self.update()
            else:
                print("My Keycode:",event.keycode)
    #text_add(repr(event.char))
    def send(self,none):
        t = "".join(self.buffer_txt)
        self.buffer_txt = []
        print("text:",t)
        self.text_add(t)
        #This is the variable I want to send to the interpret Class as an input() alternative
        self.text = t
        self.w.delete(self.txt[-1])

if __name__ == '__main__':
    thread1 = Window()
    thread2 = interpret()

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

我尝试做的是Window应该是一种更灵活的输入选择。我删除了一些不必要的代码,我希望了解我尝试做的事情仍然很好。

1 个答案:

答案 0 :(得分:0)

我能给出的最好建议是在代码中没有无限循环。您已经有一个名为mainloop的无限循环。使用它对您有利。编写一个函数,只执行循环中要执行的操作的一次迭代。然后,在该功能完成后,检查是否还有更多工作要做。如果有的话,让它使用after在几毫秒内再次调用自己。通常,这是足够的性能,您根本不需要使用任何线程。