Tkinter et threading

Tkinter et threading - Python - Programmation

Marsh Posté le 17-07-2005 à 23:36:40    

D'avance, je m'excuse à avoir à écrire un si long post.  
 
Résumé du problème:
Impossibilité d'utiliser un thread (from threading) dans une boite de dialogue modale (from tkSimpleDialog).  
 
Ci-dessous, le code source. Dans la fenêtre principale, le thread fonctionne (le disque bleu clignote). Lorsque la boite de dialogue est appelée, l'animation dans la fenêtre principale s'arrête et celle censée fonctionner dans la boite de dialogue ne se lance pas.
 
Est-ce que quelqu'un à déjà rencontrer ce problème?
 
Après quelques investigations, j'ai trouvé que c'est la fonction "self.wait_window(self)" dans tkSimpleDialog qui est la cause de ceci. Son remplacement par une boucle de traitement d'événements (voir ci-dessous), permet de résoudre en partie le problème. En partie car cela n'est pas du tout élégant et bloque de temps en temps le thread:
 


while(self.loop):
    self.update()


 
Que conseillez-vous?
 
Merci d'avance.
 
 
 
<--début du code source-->


#!/usr/bin/python
 
from Tkinter import *
from tkSimpleDialog import Dialog
from time import sleep
import threading
 
class AnimThread(threading.Thread):
 
    def __init__(self,canvas):
        threading.Thread.__init__(self)
 
        self.canvas=canvas
        self.item=self.canvas.create_oval(0,0,64,64,fill="blue" )
 
    def run(self):
        self.anim=True
        state=0
        while(self.anim):
            state=[1,0][state]
            self.canvas.itemconfigure(self.item,state=[HIDDEN,NORMAL][state])
            self.canvas.update_idletasks()
            sleep(.2)
 
    def stop(self):
        self.anim=False
 
class AnimWidget(Canvas):
 
    def __init__(self,master):
        Canvas.__init__(self,master=master,bd=1,width=64,height=64)
 
        self.thread=AnimThread(self)
 
        self.start()
 
    def start(self):
        """start the thread"""
        self.thread.start()
 
    def stop(self):
        """stop the thread"""
        self.thread.stop()
        while(self.thread.isAlive()):
            pass
        self.thread=None
 
class MyDialog(Dialog):
 
    def __init__(self,master):
        Dialog.__init__(self,parent=master,title="titre" )
 
    def cancel(self, event=None):
        self.anim.stop()
        Dialog.cancel(self,event)
 
    def body(self, master):
        self.anim=AnimWidget(master)
        self.anim.pack()
 
class Application(Tk):
 
    def __init__(self):
        Tk.__init__(self)
 
        self.mainframe=self
 
        self.anim=AnimWidget(self)
        self.anim.pack()
 
        self.btn=Button(self,text="dlg",command=self.opendialog)
        self.btn.pack()
 
    def opendialog(self):
        dlg=MyDialog(self)
 
 
if __name__ == '__main__':
    app = Application()
    app.mainloop()


<--fin du code source-->


Message édité par william o'connor le 19-07-2005 à 06:49:59
Reply

Marsh Posté le 17-07-2005 à 23:36:40   

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed