Python QT ProgressBar
Lorsque vous utilisez le code suivant ma demande stands après quelques secondes.
Et par les étals je veux dire se bloque. J'obtiens une fenêtre de Windows disant d'attendre ou de la force de fermeture.
Je pourrais ajouter que cela n'arrive que lorsque je clique sur l'intérieur de la barre de progression fenêtre ou lorsque je clique sur l'extérieur de sorte qu'il perd le focus. Si je commence à l'exemple et ne touchez à rien, il fonctionne comme il le devrait.
from PyQt4 import QtCore
from PyQt4 import QtGui
class ProgressBar(QtGui.QWidget):
def __init__(self, parent=None, total=20):
super(ProgressBar, self).__init__(parent)
self.name_line = QtGui.QLineEdit()
self.progressbar = QtGui.QProgressBar()
self.progressbar.setMinimum(1)
self.progressbar.setMaximum(total)
main_layout = QtGui.QGridLayout()
main_layout.addWidget(self.progressbar, 0, 0)
self.setLayout(main_layout)
self.setWindowTitle("Progress")
def update_progressbar(self, val):
self.progressbar.setValue(val)
L'utilisation de ce comme suit:
app = QtGui.QApplication(sys.argv)
bar = ProgressBar(total=101)
bar.show()
for i in range(2,100):
bar.update_progressbar(i)
time.sleep(1)
Merci pour toute aide.
OriginalL'auteur Tuim | 2012-11-07
Vous devez vous connecter pour publier un commentaire.
Vous devez autoriser les manifestations à être transformés, tandis que la boucle est en cours d'exécution afin que l'application puisse rester réactif.
Plus important encore, pour longtemps-tâches en cours d'exécution, vous devez fournir un moyen pour l'utilisateur d'arrêter la boucle une fois qu'il est commencé.
Une façon simple de le faire est de commencer la boucle avec une minuterie, puis périodiquement appel qApp.processEvents tandis que la boucle s'exécute.
Voici un script démo qui fait que:
Mise à JOUR
En supposant que vous êtes à l'aide de la C mise en œuvre de python (c'est à dire Disponible), la solution de cette question dépend entièrement sur la nature de la tâche(s) qui doivent s'exécuter simultanément avec l'interface graphique. Plus fondamentalement, il est déterminé par Disponible ayant une Mondial Interprète de Verrouillage (GIL).
Je ne vais pas tenter une explication de Disponible de GIL: au lieu de cela, je vais simplement vous recommandons de regarder cette excellente PyCon vidéo par Dave Beazley, et d'en rester là.
Généralement, lorsque vous essayez d'exécuter une interface graphique, en parallèle à une tâche en arrière-plan, la première question à se poser est: Est-ce la tâche IO-lié, ou le CPU?
Si c'est IO-lié (par exemple, accès au système de fichiers local, à télécharger à partir d'internet, etc), puis la solution est généralement assez simple, parce que Disponible libère toujours le GIL pour les opérations d'e/S. La tâche en arrière-plan peut être simplement fait de façon asynchrone, ou effectué par un thread de travail, et rien de spécial doit être fait pour garder le GUI réactif.
Les principales difficultés se produire avec le CPU des tâches, quand il y a une deuxième question à se poser la question: la tâche se décompose en une série de petites étapes?
S'il le peut, la solution est à envoyer régulièrement des demandes pour le thread GUI de processus actuel de la pile d'attente des événements. La démo du script ci-dessus est un bon exemple de cette technique. Plus généralement, la tâche sera exécutée dans un thread de travail séparé, qui émettraient une interface graphique-mise à jour du signal de chaque étape de la tâche est terminée. (NB: il est important de veiller à ce que le thread de ne jamais les tentatives de l'interface graphique des opérations liées à elle-même).
Mais si la tâche ne peut pas être décomposé en petites étapes, alors aucun des habituels threading-type de solutions fonctionnent. Le GUI congelez-les jusqu'à ce que la tâche a été achevée, si les fils sont utilisés ou non.
Pour ce dernier scénario, la seule solution est d'utiliser une processus, plutôt qu'un thread séparé - c'est à dire faire usage de la multitraitement module. Bien sûr, cette solution ne sera efficace que si le système cible a plusieurs cœurs de PROCESSEUR disponibles. Si il n'y a qu'un cœur de PROCESSEUR pour jouer avec, il n'y a fondamentalement rien de ce qui peut être fait pour aider les (autres que de passer à une mise en œuvre différente de Python, ou à une autre langue au total).
Mon script n'est qu'une simple démo basée sur le code dans votre question. Ce n'est pas une solution universelle qui fonctionne dans toutes les situations. Vous devez mettre à jour votre question avec une bonne explication de ce que vous essayez de faire. Quels sont ces "tâches" que vous mentionnez? Sont-ils le CPU, ou IO-lié? Est l'application qui effectue les tâches de quelque chose que vous avez écrit vous-même, et peut donc modifier? Quelle langue est-il écrit? Etc, etc.
Ces tâches sont les installations de l'e.g déballage des fichiers zip, installer msi/packages deb, des choses comme ça. Mais ce n'est pas très pertinent. L'application est écrite en Python aswell et entièrement personnalisable. Aussi, je ne m'attendais pas à un copier-coller en mesure de répondre! Je suis dans l'attente d'une pointe dans la bonne direction, et celui que vous avez ne semble pas être la bonne direction pour moi, j'ai essayé. Aucune infraction.
Au contraire: la nature des tâches est probablement le chose qui est approprié à votre cas. Consultez la mise à jour de ma réponse.
Je vous remercie pour vos réponse.
OriginalL'auteur ekhumoro
lorsque vous faites de la programmation gui vous avez besoin d'utiliser une certaine forme de multi-threading, vous avez un thread de travail et un que les mises à jour de l'interface graphique et répond à la souris et au clavier événements. Il y a un certain nombre de façons de le faire. Je vous recommande de jeter un oeil à ce QProgressBar tutoriel qui a un excellent exemple de la façon d'utiliser QProgressBar.
Dans le tuto ils sont à l'aide de QBasicTimer qui est le moyen de contrôle du rendement au thread principal afin qu'il puisse répondre à GUI événements. En utilisant
time.sleep
dans votre code, vous ne bloque pendant une seconde, le seul fil qui est en cours d'exécution.Oui, ils le sont, ne pas utiliser de
time.sleep()
.J'ai mis à jour la réponse à lui expliquer pourquoi votre code et les tutoriels ne sont pas de la même chose.
Je pense que de mentionner le filetage ici confond tout simplement les choses. Il n'y a pas de thread en cause, il est juste sur le point de rendre le contrôle de la boucle d'événement de Qt ainsi, l'application peut rester sensible. Déplacer des travaux sur des threads séparés est une stratégie pour parvenir à cela, mais elle n'est absolument pas nécessaire.
Peut-être que j'ai besoin d'ajouter un peu plus de contexte. J'ai une application console qui fait un ensemble de tâches dans une série. Je veux simplement montrer une progressbar pour cela, et depuis QT est la préférée de la bibliothèque d'interface graphique ici, je suis lié à l'utiliser. L'application n'a pas de modèle de threading, sauf pour le thread principal. Donc ce que j'ai simplement besoin d'une GUI cadre (dans un nouveau thread ou pas) pour afficher une barre de progression et la mise à jour de cette barre à chaque fois qu'une tâche est terminée.
OriginalL'auteur Marwan Alsabbagh