我是一个非常新的线程我仍然试图了解如何编写大部分代码。我正在尝试制作一个有效的文本编辑器类型输入框,因此,就像我知道的每个文本编辑器一样,我需要一个光标栏来指示文本输入的位置。因此,我也希望能够闪烁/闪烁光标,我认为这也是线程化的好习惯。
我有一个类光标,它根据我的画布文本的边界框在画布上创建一个矩形,但是当我输入更多字符时,我需要更改它的位置;当用户点击输入框外部时,停止线程并立即隐藏光标矩形;并最后重新启动线程中的线程/循环(再一次,共享一个变量) - 这里的想法是光标闪烁250次然后消失(虽然没有必要,我认为这将是一个很好的学习练习)
假设我已经捕获了触发这些事件所需的事件,那么最好的方法是什么呢?我有一些代码,但我真的认为它不会起作用,而且一直变得更加混乱。我的想法是闪烁方法本身就是线程。将整个班级改为线程会更好吗?请不要被我的代码中的想法所限制,并随时改进它。我不认为停止工作正常,因为每次我将alt + tab从窗口中取出(我已经编程脱离输入框),Python shell和tkinter GUI停止响应。
from tkinter import *
import threading, time
class Cursor:
def __init__(self, parent, xy):
self.parent = parent
#xy is a tuple of 4 integers based on a text object's .bbox()
coords = [xy[2]] + list(xy[1:])
self.obj = self.parent.create_rectangle(coords)
self.parent.itemconfig(self.obj, state='hidden')
def blink(self):
blinks = 0
while not self.stop blinks <= 250:
self.parent.itemconfig(self.obj, state='normal')
for i in range(8):
time.sleep(0.1)
if self.stop: break
self.parent.itemconfig(self.obj, state='hidden')
time.sleep(0.2)
blinks += 1
self.parent.itemconfig(self.obj, state='hidden')
def startThread(self):
self.stop = False
self.blinking = threading.Thread(target=self.blink, args=[])
self.blinking.start()
def stopThread(self):
self.stop = True
self.blinking.join()
def adjustPos(self, xy):
#I am not overly sure if this will work because of the thread...
coords = [xy[2]] + list(xy[1:])
self.parent.coords(self.obj, coords)
#Below this comment, I have extracted relevant parts of classes to global
#and therefore, it may not be completely syntactically correct nor
#specifically how I initially wrote the code.
def keyPress(e):
text = canvas.itemcget(textObj, text)
if focused:
if '\\x' not in repr(e.char) and len(e.char)>0:
text += e.char
elif e.keysym == 'BackSpace':
text = text[:-1]
canvas.itemconfig(textObj, text=text)
cursor.adjustPos(canvas.bbox(textObj))
def toggle(e):
if cursor.blinking.isAlive(): #<< I'm not sure if that is right?
cursor.stopThread()
else:
cursor.startThread()
if __name__=="__main__":
root = Tk()
canvas = Canvas(root, width=600, height=400, borderwidth=0, hightlightthickness=0)
canvas.pack()
textObj = canvas.create_text(50, 50, text='', anchor=NW)
root.bind('<Key>', keyPress)
cursor = Cursor(canvas, canvas.bbox(textObj))
#Using left-click event to toggle thread start and stop
root.bind('<ButtonPress-1', toggle)
#Using right-click event to somehow restart thread or set blinks=0
#root.bind('<ButtonPress-3', cursor.dosomething_butimnotsurewhat)
root.mainloop()
如果有更好的方法来做上面写的事情,请告诉我。 感谢。