tkinter 计时器与入口小部件一起使用

tkinter timer use with entry widgets

from  tkinter import * 
from  threading import Timer 
.......

def getdata(dval):
    global log,entryWidget,txtf,infile,lout
    ff="c:\downloads\test\logs\log1.log"
    flog=open(ff,encoding="utf-8")
    infile= flog.read()
    flog.close()  

def getlog(sval):
    global log,entryWidget,txtf,infile,lout
    txtf.delete ('1.0','end')
    inf =entryWidget.get().strip()
    if  inf == "scan":
      gdata = getdata("")
      txtf.insert (END,gdata)
   else:
     gdata=str(datetime.now( ))+"\n"
     txtf.insert (END,gdata)
   gdata=""

   ev=Timer(60,getlog,[lout])
   ev.start()

def runscan():
    global log,entryWidget,txtf,infile,lout
    root =Tk()
    root.title("Scan  log")t
    textFrame = Frame(root)
    txtf= Text(textFrame,width=60,height=18,font=("MS Sans Serif bold",8))
    entryWidget = Entry(textFrame)

    textFrame.grid(row=200,column=200)
    textFrame.bind("<Button-1>", getlog(lout)

    txtf.grid(row=0,column=1)

    entryWidget["width"] = 30
    entryWidget.bind('<Return>',getlog(10))
    entryWidget.grid(row=25,column=1)

    ev=Timer(60,getlog,[10])
    ev.start()

    root.mainloop()

if __name__ == "__main__":
    runscan()

计时器每 60 秒运行一次,但 Entrywidget 没有。
如果我取出计时器,Entrywidget 工作正常。
所以定时器线程在某个地方锁定了小部件输入。
似乎主循环中的计时器
需要重置功能而不是在 getlog 功能中。

您不需要使用计时器 class。 Tkinter 有办法在未来 运行 编写代码。 Timer class 的问题在于它使用线程,而 tkinter 不是线程安全的。

这是一个如何每 60 秒 运行 getlog 的示例。调用一次,每分钟运行直到程序退出。

def getlog():
    txtf.delete ('1.0','end')
    inf =entryWidget.get().strip()
    if  inf == "scan":
        gdata = getdata("")
        txtf.insert (END,gdata)
    else:
        gdata=str(datetime.now( ))+"\n"
        txtf.insert (END,gdata)
    gdata=""

    txtf.after(60000, getlog)

请注意,如果 getdata("") 可以阻止,这仍然会导致您的程序挂起。如果是这种情况,您将不得不继续使用线程,但您必须让您的线程获取数据并将其 post 到线程安全队列,并让您​​的 GUI 线程轮询该队列。不知道 getdata 做什么,我不能更具体。

def runscan():
    global log,entryWidget,txtf,infile,lout
    lout=10
    root =Tk()
    root.title("Scan Mirc log")
    root["padx"] = 2
    root["pady"] = 2
    root.configure(background='grey')
    w = 400 # width for the Tk root
    h = 360 # height for the Tk root
    ws = root.winfo_screenwidth() # width of the screen
    hs = root.winfo_screenheight() # height of the screen
    x = ws - w-20
    y = hs - h -60
    root.geometry('%dx%d+%d+%d' % (w, h, x, y))
    textFrame   = Frame(root)
    entryWidget = Entry(root)
    entryWidget["width"] = 30

    txtf= Text(textFrame,width=65,height=23,font=("MS Sans Serif bold",8))

    textFrame.bind("<Button-1>",getlog,[lout])
    entryWidget.bind('<Return>',getlog,[lout])

    txtf.grid(row=0,column=1)
    textFrame.grid(row=20,column=1)
    entryWidget.grid(row=30,column=1)

    txtf.after (60000,getlog,[lout])

    root.mainloop()

if __name__ == "__main__":
    runscan()  

清理并更正了一些错误
现在工作正常