2015-11-05 4 views
0
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() 

La minuterie fonctionne correctement toutes les 60 secondes, mais pas le widget d'entrée .
Si je sors la minuterie le Entrywidget fonctionne bien.
Donc, quelque part le thread minuteur verrouille l'entrée du widget.
Il semblerait que le temporisateur dans la boucle principale
nécessite une fonction de réinitialisation et non dans la fonction getlog.Utilisation de la minuterie tkinter avec les widgets d'entrée

Répondre

2

Vous n'avez pas besoin d'utiliser la classe Timer. Tkinter a un moyen d'exécuter du code dans le futur. Le problème avec la classe Timer est qu'elle utilise des threads, et tkinter n'est pas thread-safe.

Voici un exemple de la façon d'exécuter getlog toutes les 60 secondes. Appelez-le une fois, et il fonctionnera toutes les minutes jusqu'à ce que le programme se termine.

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) 

Notez que si getdata("") peut bloquer, ce sera toujours la cause de votre programme pour accrocher. Si c'est le cas, vous devrez continuer à utiliser des threads, mais vous devrez faire en sorte que votre thread récupère les données et les poste dans une file d'attente thread-safe, et que votre thread graphique interroge cette file d'attente. Sans savoir ce que fait getdata, je ne peux pas être plus précis.

+0

Merci Bryan vérifier –

+0

ne fonctionne pas entryWidget est toujours accroché. –

+0

@MNewton: bien, si 'getdata (" ")' peut bloquer, alors oui, cela provoquera le blocage de votre programme. Puisque vous n'avez pas envoyé le code pour 'getdata', il est impossible de le dire avec certitude. –

0
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() 

nettoyé et corrigé quelques erreurs
et il fonctionne très bien maintenant