Threading в pyqt4 - PullRequest
       5

Threading в pyqt4

3 голосов
/ 28 июля 2011

В моем графическом интерфейсе я должен загружать много вещей между ними.Я использую urllib, чтобы сделать это.проблема, конечно же, заключается в том, что графический интерфейс пользователя зависает до тех пор, пока все не будет загружено.

Мой код похож на следующий:

QtCore.QObject.connect( self.UI.commandLinkButton_2 , QtCore.SIGNAL("clicked()") , self.addStoryToHistory )

, в котором вышеуказанная функция имеет код загрузки.1007 * Это не что иное, как отправка общих данных между ними, и этот процесс просто включает загрузку данных в определенное местоположение.

Какой самый простой способ не заморозить мой графический интерфейс?Должен ли я использовать multiprocessing или QThreads?

Может кто-нибудь указать мне на некоторые ссылки ... Я не хочу, чтобы это было очень сложно, поэтому, если есть какой-то более простой способ сделать это, пожалуйста, укажите это....

Большое спасибо ...

Ответы [ 2 ]

5 голосов
/ 28 июля 2011

Вот пример, который я только что снял с проекта, над которым работал пару месяцев назад, используя в качестве основы пример http из PyQt.Он загрузит SIP с сайта Riverbank.

Он использует QHttp из QtNetwork вместо urllib, а индикатор выполнения подключен к его сигналу dataReadProgress .Это должно позволить вам надежно загрузить файл, а также иметь отзывчивый графический интерфейс.

from PyQt4.QtCore import QUrl, QFileInfo, QFile, QIODevice
from PyQt4.QtGui import QApplication, QDialog, QProgressBar, QLabel, QPushButton, QDialogButtonBox, \
                    QVBoxLayout, QMessageBox
from PyQt4.QtNetwork import QHttp

url_to_download = 'http://www.riverbankcomputing.co.uk/static/Downloads/sip4/sip-4.12.3.zip'

class Downloader(QDialog):
    def __init__(self, parent=None):
        super(Downloader, self).__init__(parent)

        self.httpGetId = 0
        self.httpRequestAborted = False
        self.statusLabel = QLabel('Downloading %s' % url_to_download)
        self.closeButton = QPushButton("Close")
        self.closeButton.setAutoDefault(False)
        self.progressBar = QProgressBar()

        buttonBox = QDialogButtonBox()
        buttonBox.addButton(self.closeButton, QDialogButtonBox.RejectRole)

        self.http = QHttp(self)
        self.http.requestFinished.connect(self.httpRequestFinished)
        self.http.dataReadProgress.connect(self.updateDataReadProgress)
        self.http.responseHeaderReceived.connect(self.readResponseHeader)
        self.closeButton.clicked.connect(self.cancelDownload)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.statusLabel)
        mainLayout.addWidget(self.progressBar)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)

        self.setWindowTitle('Download Example')
        self.downloadFile()

    def downloadFile(self):
        url = QUrl(url_to_download)
        fileInfo = QFileInfo(url.path())
        fileName = fileInfo.fileName()

        if QFile.exists(fileName):
            QFile.remove(fileName)

        self.outFile = QFile(fileName)
        if not self.outFile.open(QIODevice.WriteOnly):
            QMessageBox.information(self, 'Error',
                    'Unable to save the file %s: %s.' % (fileName, self.outFile.errorString()))
            self.outFile = None
            return

        mode = QHttp.ConnectionModeHttp
        port = url.port()
        if port == -1:
            port = 0
        self.http.setHost(url.host(), mode, port)
        self.httpRequestAborted = False

        path = QUrl.toPercentEncoding(url.path(), "!$&'()*+,;=:@/")
        if path:
            path = str(path)
        else:
            path = '/'

        # Download the file.
        self.httpGetId = self.http.get(path, self.outFile)

    def cancelDownload(self):
        self.statusLabel.setText("Download canceled.")
        self.httpRequestAborted = True
        self.http.abort()
        self.close()

    def httpRequestFinished(self, requestId, error):
        if requestId != self.httpGetId:
            return

        if self.httpRequestAborted:
            if self.outFile is not None:
                self.outFile.close()
                self.outFile.remove()
                self.outFile = None
            return

        self.outFile.close()

        if error:
            self.outFile.remove()
            QMessageBox.information(self, 'Error',
                    'Download failed: %s.' % self.http.errorString())

        self.statusLabel.setText('Done')       

    def readResponseHeader(self, responseHeader):
        # Check for genuine error conditions.
        if responseHeader.statusCode() not in (200, 300, 301, 302, 303, 307):
            QMessageBox.information(self, 'Error',
                    'Download failed: %s.' % responseHeader.reasonPhrase())
            self.httpRequestAborted = True
            self.http.abort()

    def updateDataReadProgress(self, bytesRead, totalBytes):
        if self.httpRequestAborted:
            return
        self.progressBar.setMaximum(totalBytes)
        self.progressBar.setValue(bytesRead)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    downloader = Downloader()
    downloader.show()
    sys.exit(app.exec_())
0 голосов
/ 28 июля 2011

Я предлагаю вам вместо этого использовать QNetworkManager и следить за процессом загрузки.

Смотрите этот другой вопрос: pyQT QNetworkManager и ProgressBars

...