Rumah > Artikel > pembangunan bahagian belakang > Bagaimanakah Saya Boleh Mengemas kini GUI PyQt dengan Cekap daripada Berbilang Benang?
Dalam dunia pengaturcaraan berbilang benang dengan PyQt, cabaran biasa timbul: cara mengemas kini GUI dengan cekap sebagai tindak balas kepada tindakan yang dilakukan dalam benang berasingan. Artikel ini bertujuan untuk memberikan contoh dan cerapan praktikal untuk mencapai kemas kini GUI yang responsif dan disegerakkan dalam aplikasi sedemikian.
Satu pendekatan ialah menghantar rujukan kepada elemen GUI kepada urutan. Dalam urutan, anda boleh mengemas kini komponen UI secara langsung. Walau bagaimanapun, adalah penting untuk ambil perhatian bahawa widget Qt tidak selamat untuk thread dan hanya boleh diakses dari thread utama. Dokumentasi PyQt sangat menasihatkan agar tidak mengakses elemen GUI daripada utas selain daripada utas utama.
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_())
Lebih selamat dan lebih dipercayai cara untuk mengemas kini GUI daripada benang adalah melalui isyarat dan slot. Isyarat membolehkan anda memancarkan peristiwa tersuai daripada urutan, yang GUI boleh dengar dan kendalikan dengan sewajarnya.
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_())
Dengan memanfaatkan isyarat dan slot, kami memastikan semua kemas kini GUI berlaku dalam utas utama, mengekalkan keselamatan utas dan mencegah kemungkinan ralat.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengemas kini GUI PyQt dengan Cekap daripada Berbilang Benang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!