Найти - Пользователи
Полная версия: Qt + Thread = не работает setText со стилями.
Начало » GUI » Qt + Thread = не работает setText со стилями.
1
degid
Всем привет.
Подскажите плиз, почему из потока не удается выполнить setText со стилем или setStyleSheet?
from PyQt4 import QtCore, QtGui, uic
import sys
import threading
class Get(threading.Thread):
    def __init__(self, label_message):
        threading.Thread.__init__(self)
        self.label_message = label_message
    def run(self):
        if win_project.testflag:
            self.label_message.setText(u'<b style="color:red;">Test 1</b>')
            win_project.testflag = False
        else:
            self.label_message.setText(u'Test 2')
            self.label_message.setStyleSheet('Qlabel {color: red;}')
            win_project.testflag = True
class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.training = uic.loadUi("include/test2.ui")
        self.training.show()
        self.testflag = False
        self.connect(self.training.pushButton_get_image, QtCore.SIGNAL("clicked()"), self.GetImage)
    def GetImage(self):
        self.th = Get(self.training.label_message)
        self.th.start()
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    win_project = MainWindow()
    sys.exit(app.exec_())
На
self.label_message.setText(u'<b style="color:red;">Test 1</b>')
ошибка:
QPixmap: It is not safe to use pixmaps outside the GUI thread
а на:
self.label_message.setStyleSheet('Qlabel {color: red;}')
ошибка:
(Parent is QLabel(0x1e00610), parent\'s thread is QThread(0x2361ab8), current thread is QThread(0x24f9ca8)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(0x24f9cb8), parent\'s thread is QThread(0x24f9ca8), current thread is QThread(0x2361ab8)
Хотя если выполнять setText с простым текстом, то все работает. Как заставить работать стили?
degid
Я так понял, можно решить как тут, но что-то я не могу это всё дело подогнать к своему примеру
ajib6ept
degid
Я так понял, можно решить как тут, но что-то я не могу это всё дело подогнать к своему примеру

В чем сложность? надо передавать через сигнал в главный поток.
Вот тут и тут можно посмотреть реализацию многопоточности через QThread
degid
ajib6ept
спасибо, по первому примеру всё получилось

from PyQt4 import QtCore, QtGui, uic
import sys
import Queue
class Task(object):
    error = None
class TaskPool(object):
    def __init__(self, size):
        self._pool = []
        self._queue = Queue.Queue()
        for _ in range(size):
            print '2'
            t = Thread(self._queue)
            self._pool.append(t)
            QtCore.QObject.connect(t, QtCore.SIGNAL('taskDone(PyQt_PyObject, PyQt_PyObject)'), self._done)
            t.start()
    def put(self, task, callback=None):
        self._queue.put((task, callback))
    def _done(self, task, callback):
        if callback:
            callback(task)
class Thread(QtCore.QThread):
    def __init__(self, queue):
        QtCore.QThread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            task, callback = self.queue.get()
            try:
                task()
            except:
                task.error = sys.exc_info()
            print '3'
            self.emit(QtCore.SIGNAL('taskDone(PyQt_PyObject, PyQt_PyObject)'), task, callback)
class MyTask(Task):
    # через конструктор передаем любые параметры
    def __init__(self):
        pass
    # метод, который будет вызван в потоке
    def __call__(self):
        Get()
class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.training = uic.loadUi("include/test2.ui")
        self.training.show()
        self.testflag = False
        self.connect(self.training.pushButton_get_image, QtCore.SIGNAL("clicked()"), self.GetImage)
        self.pool = TaskPool(1)
    def GetImage(self):
        print '1', self.testflag
        task = MyTask()
        self.pool.put(task, self.callback)
    def callback(self, task):
        if self.testflag:
            self.training.label_message.setText(u'<b style="color:red;">Test 1</b>')
        else:
            self.training.label_message.setText(u'<b style="color:blue;">Test 2</b>')
def Get():
    print '4', win_project.testflag
    if win_project.testflag:
        win_project.testflag = False
    else:
        win_project.testflag = True
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    win_project = MainWindow()
    sys.exit(app.exec_())
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB