Maison > développement back-end > Tutoriel Python > Comment puis-je mettre à jour efficacement une interface graphique PyQt à partir de plusieurs threads ?

Comment puis-je mettre à jour efficacement une interface graphique PyQt à partir de plusieurs threads ?

Mary-Kate Olsen
Libérer: 2024-11-19 19:33:02
original
372 Les gens l'ont consulté

How Can I Efficiently Update a PyQt GUI from Multiple Threads?

Mises à jour de l'interface graphique en temps réel dans les applications PyQT multithread

Dans le monde de la programmation multithread avec PyQt, un défi commun se pose : comment mettre à jour efficacement l'interface graphique en réponse à actions effectuées dans des threads séparés. Cet article vise à fournir des exemples pratiques et des informations sur la manière d'obtenir des mises à jour d'interface graphique réactives et synchronisées dans de telles applications.

Approche de transmission de référence

Une approche consiste à transmettre des références aux éléments de l'interface graphique aux threads. Dans les fils de discussion, vous pouvez directement mettre à jour les composants de l'interface utilisateur. Cependant, il est crucial de noter que les widgets Qt ne sont pas thread-safe et ne doivent être accessibles qu'à partir du thread principal. La documentation PyQt déconseille fortement d'accéder aux éléments de l'interface graphique à partir de threads autres que le thread principal.

Exemple de code :

import sys
import urllib2

from PyQt4 import QtCore, QtGui


class DownloadThread(QtCore.QThread):
    def __init__(self, url, list_widget):
        QtCore.QThread.__init__(self)
        self.url = url
        self.list_widget = list_widget

    def run(self):
        info = urllib2.urlopen(self.url).info()
        self.list_widget.addItem('%s\n%s' % (self.url, info))


class MainWindow(QtGui.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.list_widget = QtGui.QListWidget()
        self.button = QtGui.QPushButton("Start")
        self.button.clicked.connect(self.start_download)
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.list_widget)
        self.setLayout(layout)

    def start_download(self):
        urls = ['http://google.com', 'http://twitter.com', 'http://yandex.ru',
                'http://stackoverflow.com/', 'http://www.youtube.com/']
        self.threads = []
        for url in urls:
            downloader = DownloadThread(url, self.list_widget)
            self.threads.append(downloader)
            downloader.start()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())
Copier après la connexion

Approche des signaux et des emplacements

Une approche plus sûre et plus fiable La façon de mettre à jour l'interface graphique à partir des threads consiste à utiliser des signaux et des emplacements. Les signaux vous permettent d'émettre des événements personnalisés à partir de threads, que l'interface graphique peut écouter et gérer de manière appropriée.

Exemple de code :

import sys
import urllib2

from PyQt4 import QtCore, QtGui


class DownloadThread(QtCore.QThread):

    data_downloaded = QtCore.pyqtSignal(object)

    def __init__(self, url):
        QtCore.QThread.__init__(self)
        self.url = url

    def run(self):
        info = urllib2.urlopen(self.url).info()
        self.data_downloaded.emit('%s\n%s' % (self.url, info))


class MainWindow(QtGui.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.list_widget = QtGui.QListWidget()
        self.button = QtGui.QPushButton("Start")
        self.button.clicked.connect(self.start_download)
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.button)
        layout.addWidget(self.list_widget)
        self.setLayout(layout)

        # Connect our signal to our slot
        self.thread = DownloadThread()
        self.thread.data_downloaded.connect(self.on_data_ready)

    def start_download(self):
        urls = ['http://google.com', 'http://twitter.com', 'http://yandex.ru',
                'http://stackoverflow.com/', 'http://www.youtube.com/']
        self.threads = []
        for url in urls:
            downloader = DownloadThread(url)
            downloader.data_downloaded.connect(self.on_data_ready)
            self.threads.append(downloader)
            downloader.start()

    def on_data_ready(self, data):
        print data
        self.list_widget.addItem(unicode(data))


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())
Copier après la connexion

En exploitant les signaux et les emplacements, nous garantissons que toutes les mises à jour de l'interface graphique se produisent dans le thread principal, maintenant la sécurité des threads et empêchant les erreurs potentielles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal