>  기사  >  백엔드 개발  >  여러 스레드에서 PyQt GUI를 효율적으로 업데이트하려면 어떻게 해야 합니까?

여러 스레드에서 PyQt GUI를 효율적으로 업데이트하려면 어떻게 해야 합니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-11-19 19:33:02326검색

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

멀티스레드 PyQT 애플리케이션의 실시간 GUI 업데이트

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.