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.
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.
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_())
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.
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_())
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!