LINUX.ORG.RU

Ерунда с нитками в PyQT4


0

0

Осваиваю PyQt. 
Разбираюсь с нитками. 
Конкретно меня интересует следующее, какая-то нитка вырабатывает
сигнал и передаёт произвольный питоновский объект в основной цикл
разбора сообщений. 

Делаю следующее:

class Producer(QThread):
    def __init__(self, parent=None):
        QThread.__init__(self, parent)
        
        self.keep_running = True
        self.count = 0
        self.active = False
    
    def activate(self):
        self.active = True
    
    def deactivate(self):
        self.active = False
    
    def run(self):
        while self.keep_running:
            self.count += 1

            # Вот именно 300 или что здесь указать зачасутю передаётся
            # вместо словаря с данными
            self.msleep(300)
            
            d = {
                'time': time.time(),
                'count': self.count }
            
            self.d = d
            
            # Тут пробовал указывать и d и self.d
            if self.active:
                self.emit(SIGNAL('newData'), dict(d))

class Logic(QObject):
    def __init__(self, widget):
        QObject.__init__(self)
        
        self.widget = widget
        self.text = self.widget.text
        self.start_button = self.widget.start_button
        self.stop_button = self.widget.stop_button
        
        self.thread = Producer()
        
        self.connect(self.start_button, SIGNAL('clicked()'),
            self.thread.activate)
        self.connect(self.stop_button, SIGNAL('clicked()'),
            self.thread.deactivate)

        # Здесь пробовал Qt.QueuedConnection не указывать. Та же фигня
        self.connect(self.thread, SIGNAL('newData'), self.processData,
            Qt.QueuedConnection)
        self.connect(self.thread, SIGNAL('text(QString)'), self.text.append)
        
        self.thread.start()
    
    def processData(self, data):
        print data
        print type(data)

И косяк в том что Logic.processData() иногда печатает то что надо,
т.е. словарь а иногда (даже скорее как правило :-() передаётся
значение аргумента Producer.msleep() 8-() 

Знатоки PyQT, что я делаю не так? И как это надо делать?

P.S. В wxPython-е такое работает на ура :-)

Ответ на: комментарий от ero-sennin

А как вообще на PyQT решается такая задача?

Т.е. нам надо передать из отдельной нитки какие-то данные в основную нитку. Неужели надо импользовать какие-то разделяемые данные и синхронихацию по мутехам?

redvasily
() автор топика
Ответ на: комментарий от redvasily

> А как вообще на PyQT решается такая задача?

Сигналы одной нити, конечно, можно подключать к слотам другой нити, но работать они будут всё равно синхронно, поэтому обычно используется QApplication.postEvent(sender, receiver) и соответствующий обработчик. Ну или разделяемые данные с мутексами. :)

ero-sennin ★★
()
Ответ на: комментарий от ero-sennin

#!/usr/bin/env python

# Вот примерно так оно делается.

import sys
from PyQt4.QtCore import QEvent, QThread
from PyQt4.QtGui import QApplication, QTextEdit

class MyEvent(QEvent):
    def __init__(self, data):
        QEvent.__init__(self, QEvent.User)
        self.data = data

class Timer(QThread):
    def __init__(self, event_receiver):
        QThread.__init__(self)
        self.event_receiver = event_receiver
        self.time = 0
    def run(self):
        while True:
            self.time += 1
            QApplication.postEvent(self.event_receiver, MyEvent(self.time))
            self.sleep(1)

class Display(QTextEdit):
    def customEvent(self, event):
        if isinstance (event, MyEvent):
            self.append('time = %i' % event.data)

a = QApplication(sys.argv)
display = Display()
display.show()

timer = Timer(display)
timer.start()

sys.exit(a.exec_())

ero-sennin ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.