Ошибка потоковой передачи PyQT при передаче сигнала QMessageBox

Я попытался получить строку из потока в свой основной графический интерфейс с помощью СИГНАЛОВ. Все работает нормально, пока я не захочу использовать строку в QMessageBox. Распечатка не проблема, но запуск QMessageBox дает мне несколько ошибок (некоторые из них касаются QPixmap, которые я даже не использую в графическом интерфейсе.

Вот небольшой рабочий пример моего кода:

import sys
import urllib2
import time
from PyQt4 import QtCore, QtGui


class DownloadThread(QtCore.QThread):
    def __init__(self):
        QtCore.QThread.__init__(self)


    def run(self):
        time.sleep(3)
        self.emit(QtCore.SIGNAL("threadDone(QString)"), 'test')


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)

        self.downloader = DownloadThread()
        self.connect(self.downloader, QtCore.SIGNAL("threadDone(QString)"), self.threadDone, QtCore.Qt.DirectConnection)

    def start_download(self):
        self.downloader.start()

    def threadDone(self, info_message):
        print info_message
        QtGui.QMessageBox.information(self,
                    u"Information",
                    info_message
                    )
        #self.show_info_message(info_message)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

Я получаю эту ошибку:

QObject :: setParent: невозможно установить родителя, новый родитель находится в другом потоке

QPixmap: использование растровых изображений вне потока графического интерфейса небезопасно.

Эта ошибка только при перемещении мыши и QMessageBox все еще открыт:

QObject :: startTimer: таймеры не могут быть запущены из другого потока

QApplication: фильтр событий объекта не может находиться в другом потоке.

Кто-нибудь может сказать мне, что я делаю не так?

Я впервые использую потоки.

Спасибо! Стефани


person honeymoon    schedule 30.07.2013    source источник


Ответы (1)


QtCore.Qt.DirectConnection - эта опция означает, что слот будет вызываться из потока сигнала. В вашем коде есть (как минимум) два запущенных потока: основной поток графического интерфейса пользователя и DownloadThread. Таким образом, с этой опцией программа пытается вызвать threadDone из DownloadThread и пытается создать объект GUI вне потока GUI.

Это приводит к: QPixmap: It is not safe to use pixmaps outside the GUI thread

Удалите этот параметр, и поведение по умолчанию (дождитесь возврата в основной поток перед вызовом слота) должно устранить ошибку.

person Radio-    schedule 30.07.2013