web-dev-qa-db-fra.com

Multi-threading dans l'application conçue rapidement

J'ai un arbre que je remplis avec une liste de fichiers depuis mon ordinateur en cliquant sur un bouton. Pendant que le programme remplit l'arborescence, l'interface graphique entière se bloque.

Existe-t-il un moyen de remplir l'arborescence dans un autre thread afin que l'arborescence soit remplie lorsque les fichiers sont trouvés et non lorsque tout a déjà été ajouté? Ou d'autres idées?

Voici à quoi ça ressemble:

Screenshot of App

Je remplis l'arbre avec ce code:

def traversePaths(self, path, parent):
        files = os.listdir(path)
        files.sort()
        for myfile in files:
            if myfile[0] != ".":
                if os.path.isdir(path + os.sep + myfile):
                    current = self.filelist.append(parent,[self.dirIcon,self.dirIcon,self.dirOpenIcon,myfile,"DD",True,True,3])
                    self.traversePaths(path + os.sep + myfile, current)
                else:
                    current = self.filelist.append(parent,[self.fileIcon,self.dirIcon,self.dirOpenIcon,myfile,"AA",True,True,3])

qui s'exécute sur un clic de bouton:

def on_refreshbutton_clicked(self, button):
    self.traversePaths(self.path.get_filename(), None)

Je ne pense pas que threading.Thread fonctionne à cause du thread gtk pour l'interface graphique et ne trouve pas les api gi.repository.Gtk sur le sujet

Des idées?

1
ender

Lorsque vous posez des questions de programmation, il est toujours préférable de fournir un exemple de travail minimal et pas seulement des extraits de code.

Sans un exemple de travail avec lequel jouer, j'ai les suggestions suivantes:

  1. Utilisez un fil pour parcourir l'arborescence de répertoires et placez vos résultats dans un deuxième modèle d'arbre séparé (non connecté à un arbre). Cela signifie que vous avez deux modèles d'arbre, l'un connecté (qui est rendu à l'écran) et l'autre non connecté (qui n'est donc pas rendu)
  2. Ajoutez un délai d'expiration de quelques secondes, qui appelle une fonction qui détache et supprime le premier treemodel, copie le deuxième treemodel dans un nouveau, qui sert maintenant de treemodel "thread" et attache le deuxième modèle d'arbre.

La raison pour laquelle vous voyez le blocage de l'interface graphique est que le marcheur de fichiers prend très longtemps et chaque fois que vous ajoutez un fichier, beaucoup de surcharge dans Gtk est appelée. En ajoutant un treemodel complet, cette surcharge n'est appelée qu'une seule fois. Et en utilisant un thread pour la marche du fichier, votre interface graphique reste réactive.

Quant à la partie de threading dans Gtk, vous voudrez peut-être regarder ici: https://stackoverflow.com/questions/8120860/python-doing-some-work-on-background-with-gtk-gui =

Quelques notes à votre code:

  • Python a un marcheur de fichiers intégré, qui pourrait être plus rapide mais certainement plus court que votre code: os.walk
  • Si vous souhaitez utiliser votre code à la place, n'oubliez pas que Python a une limite de récursivité intégrée. En fonction de la taille de votre système de fichiers, vous souhaiterez peut-être remplacer la récursivité par une construction de type trampoline
2
xubuntix