IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Progress bar en multi-threading


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 15
    Par défaut Progress bar en multi-threading
    Bonjour à tous

    dans un programme, j'ai une portion de code qui effectue des copies de fichiers. Mon problème c'est que la GUI est figée pendant cette copie, et donc je me suis dit que ce serait pas mal d'ajouter une Progress Bar.
    Après un 1er essai où la progress bar, elle aussi, reste figée pendant la copie, je me suis penchée sur le multi-threading. Mais là, je n'arrive à rien :/

    Voilà un bout du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    class Files_copy_setup(Tkinter.Tk):	#Copy the selected file(s) in local
    	def __init__(self, parent):
    		Tkinter.Tk.__init__(self, parent)
    		self.parent = parent
    		self.initialize()
     
    	def initialize(self):
    		self.grid()
    		texte = Tkinter.Label(self, text = copied_files_text, fg = "white", bg = "blue")
    		texte.grid(row = 0, sticky = 'EWN')
    		j = 0
    		for elt in input_values.files_to_detect:
    			self.texte = Tkinter.Label(self, text=elt, fg = "black", bg = "red")
    			self.texte.grid(row = 2 + j)
    			j = j + 1
    		button_continue = ttk.Button(self, text = u"Continue", command = self.OnButtonClickContinue)
    		button_continue.grid(row = (len(input_values.files_to_detect) + 3), sticky = 'S')
    		button_back = Tkinter.Button(self, text = u"Back", command = self.OnButtonClickBack)
    		button_back.grid(row = (len(input_values.files_to_detect) + 4), sticky = 'S')
    		button_kill = Tkinter.Button(self, text = u"Quit", command = self.OnButtonClickKill)
    		button_kill.grid(row = (len(input_values.files_to_detect) + 5), sticky = 'S')
     
    		self.alive = ttk.Progressbar(self, orient = "horizontal", length = 200, mode = "indeterminate")
    		self.alive.grid(row = (len(input_values.files_to_detect) + 6), sticky = 'S')
    		self.update()
    		self.geometry("%dx%d+%d+%d" % (self.winfo_reqwidth(), self.winfo_reqheight(), (self.winfo_screenwidth() - self.winfo_reqwidth()) / 2, (self.winfo_screenheight() - self.winfo_reqheight()) / 2))
    		self.resizable(False, False)
    		self.geometry(self.geometry())
    		self.mainloop()
     
    	def OnButtonClickContinue(self):
     
    		self.alive.start()
    		input_values.completion = 1
     
    		for i in input_values.files_to_detect:
    			full_file_name2 = os.path.join(input_values.path_video, i)
    			if not(os.path.isfile(full_file_name2)):
    				thread_copy = threading.Thread(shutil.copy(os.path.join(input_values.path_video_remote, i), input_values.path_video))
    				thread_copy.start()
     
    		self.destroy()
     
    	def OnButtonClickBack(self):
    		app = Fourth_Variable_Choice_remote(None)
    		input_values.completion = 0
    		self.destroy()
     
    	def OnButtonClickKill(self):
    		input_values.completion = 0
    		input_values.next_step_var = 1
    		self.destroy()
    Et comme je ne maitrise ni la Progress Bar, ni le threading, je sais pas du tout comment faire en sorte que ça fonctionne...

    Si qq'un peut m'éclairer là-dessus, ce serait bien urbain

  2. #2
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Vous devez incrémenter* self.alive (.step(valeur)) dans la boucle de OnButtonClickContinue.
    Soit vous le faite dans le for soit lorsque un thread se termine (plus réaliste).
    Dans le cadre de for c'est simple (voir l'exemple)
    Dans le cadre du thread il faudra en faire une classe.
    Attention, évitez de toucher un objet Tk à partir du thread lui même.

    @+

    *
    Un exemple. Ici Sample simule une progression, tout comme votre for dans la liste.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    try:
        import tkinter as Tk
        from tkinter import ttk
    except:
        import Tkinter as Tk
        import ttk
     
     
     
    def Sample(val, event=None, ival=1):
        pb.step(ival)
        val += ival
        l.config(text=str(val))
        if val != maxl:
            root.after(100, lambda: Sample(val))
        else:
            l.config(text="FIN")
            btn.config(text="Quitter", command=root.quit)
     
    maxl = 500
    root = Tk.Tk()
    root.title('test: ttk.Progressbar')
    l = Tk.Label(root)
    l.pack(padx=5, pady=5)
    pb = ttk.Progressbar(root, length=maxl, maximum=maxl)
    pb.pack(padx=5, pady=5)
    btn = Tk.Button(root, text="Lancer le test")
    btn.bind("<Button-1>", lambda e: Sample(0, e))
    btn.pack(padx=5, pady=5)
    root.mainloop()
    Edit: Oups. Pas fonction mais classe.

  3. #3
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 15
    Par défaut
    OK, merci. Je suis pas sur d'avoir tout saisi, mais je vais essayer à partir de là

  4. #4
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 15
    Par défaut
    J'ai essayé, mais j'y arrive pas du tout...
    Là, la progress bar se déclenche une fois que la copie est finie, et le programme n'enchaine pas sur la suite de mon code...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    	def OnButtonClickContinue(self):
    		self.alive.start()
    		input_values.completion = 1
    		val = 0
    		ival = 1
    		maxl = 50
     
    		for i in input_values.files_to_detect:
    			full_file_name2 = os.path.join(input_values.path_video, i)
    			self.alive.step(ival)
    			val += ival
    			if val != maxl:
    				self.after(100)
    			else:
    				pass
    			if not(os.path.isfile(full_file_name2)):
    				shutil.copy(os.path.join(input_values.path_video_remote, i), input_values.path_video)
    		self.alive.mainloop()
    		self.destroy()

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    C'est plutôt:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        def OnButtonClickContinue(self):
            input_values.completion = 1
            val = 0
            self.alive.config(maximun=len(input_values.files_to_detect))
            for i in input_values.files_to_detect:
                full_file_name2 = os.path.join(input_values.path_video, i)
                if not os.path.isfile(full_file_name2):
                    shutil.copy(os.path.join(input_values.path_video_remote, i), input_values.path_video)
                val += 1
                self.alive.step(val)
            self.destroy()
    @+

    Edit: maxl est inutile ici.
    Edit 2: Attention ! Lors de mes réponses je transforme vos tabulations par 4 espaces.

  6. #6
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 15
    Par défaut
    C'est un peu mieux, mais j'ai toujours le même souci :
    la progress bar reste figée pendant la copie de fichiers :/

    Il va falloir que je passe par les threads je pense

    Merci encore, je vais tester 2-3 trucs et revenir ici si je sèche encore

Discussions similaires

  1. [Débutant] Progress bar dans un nouveau thread ?
    Par yayou49 dans le forum VB.NET
    Réponses: 6
    Dernier message: 30/03/2015, 11h45
  2. [Débutant] BackgroundWorker, Progress Bar et utilisation de Thread multiples ?
    Par iOops dans le forum VB.NET
    Réponses: 9
    Dernier message: 12/03/2013, 19h26
  3. Thread, delegate, join, process et progress bar
    Par LsMarx dans le forum Windows Forms
    Réponses: 4
    Dernier message: 06/08/2012, 13h18
  4. Progress bar et thread
    Par Invité dans le forum C#
    Réponses: 2
    Dernier message: 21/02/2012, 22h49
  5. Thread, Fenêtre Modal et Progress Bar
    Par Angelinsky7 dans le forum C#
    Réponses: 7
    Dernier message: 24/09/2009, 23h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo