PyQt를 사용한 멀티스레드 프로그래밍 세계에서 공통적인 문제가 발생합니다. 별도의 스레드에서 수행되는 작업. 이 기사의 목적은 이러한 애플리케이션에서 반응적이고 동기화된 GUI 업데이트를 달성하기 위한 실용적인 예와 통찰력을 제공하는 것입니다.
한 가지 접근 방식은 GUI 요소에 대한 참조를 스레드에 전달하는 것입니다. 스레드 내에서 UI 구성요소를 직접 업데이트할 수 있습니다. 그러나 Qt 위젯은 스레드로부터 안전하지 않으며 기본 스레드에서만 액세스해야 한다는 점을 기억하는 것이 중요합니다. PyQt 문서에서는 메인 스레드가 아닌 스레드에서 GUI 요소에 액세스하지 말 것을 강력히 권고합니다.
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_())
더 안전하고 안정적입니다. 스레드에서 GUI를 업데이트하는 방법은 신호와 슬롯을 이용하는 것입니다. 신호를 사용하면 GUI가 적절하게 수신하고 처리할 수 있는 스레드에서 사용자 정의 이벤트를 내보낼 수 있습니다.
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_())
신호와 슬롯을 활용하여 모든 GUI 업데이트가 보장됩니다. 메인 스레드 내에서 발생하여 스레드 안전성을 유지하고 잠재적인 오류를 방지합니다.
위 내용은 여러 스레드에서 PyQt GUI를 효율적으로 업데이트하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!