Форум сайта python.su
Привет.
Есть форма в которую импортирую собственный класс (QObject).
Форма запускает поток QThread,
Поток QThread обращается к импортированному классу за методом.
Метод циклично сигнализирует.
Форма должна принимать эти сигналы и вписывать их значение в ListWidget. Но вот почему то не принимает…
Пробовал QThread'ом принимать сигнал, а потом передавать его на форму - не получилось тоже.
Как правильно принять сигнал?
#mainForm.py
# Форма содержит кнопку "GO" и ListWidget
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from Ui_form import *
from myclasses import MYCLASS
class DoWork(QThread):
def __init__(self):
QThread.__init__(self)
self.mycl = MYCLASS()
def run(self):
#Вызываем функцию из импортированного класса QObject
self.mycl.printMsg()
def __del__(self):
self.exiting = True
self.wait()
class MainForm(QMainWindow):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.ui = Ui_MainForm()
self.ui.setupUi(self)
self.ui.getBasesButton.clicked.connect(goButton_OnClick)
#Нажатие на кнопку GO
def goButton_OnClick(self):
self.mycl = MYCLASS()
self.t = DoWork()
self.mycl.strSignal.connect(self.addToList, type=Qt.QueuedConnection)
self.t.start()
#Слот добавляет полученный текст в ListWidget
@pyqtSlot(str)
def addToList(self, msg)
self.ui.listWidget.addItem(msg)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
myapp = MainForm()
myapp.show()
sys.exit(app.exec_())
#myclasses.py
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MYCLASS(QObject):
strSignal = pyqtSignal(str)
def __init__(self):
QObject.__init__(self)
def printMsg(self):
while True:
i += 1
self.strSignal.emit(str(i))
time.sleep(0.1)
if i == 10:
break
Отредактировано (Дек. 14, 2010 14:35:50)
Офлайн
знакомая проблема :)
читай http://python.su/forum/viewtopic.php?id=6829
Офлайн
этот мусор нужно убрать :)
def __del__(self):
self.exiting = True
self.wait()
Офлайн
Спасибо за помощь, но можно небольшой пример используя мой код?
Просто я то-то не въеду никак, хотя перечитал пост много раз))
Кстати хочу этот класс сделать независимым, т. е. чтоб где угодно и кто угодно мог его импортировать и использовать. Модуль в общем.
Может использовать не QObject?
Офлайн
Суть в том, что сигнал должен посылать объект потока.
Oкей, держи готовый код.
taskpool.py
# coding: utf8
import sys
import Queue
from PyQt4.QtCore import QThread, SIGNAL, QObject
class Task(object):
error = None
class Thread(QThread):
def __init__(self, queue):
QThread.__init__(self)
self.queue = queue
def run(self):
while True:
task, callback = self.queue.get()
try:
task()
except:
task.error = sys.exc_info()
self.emit(SIGNAL('taskDone(PyQt_PyObject, PyQt_PyObject)'), task, callback)
class TaskPool(object):
def __init__(self, size):
self._pool = []
self._queue = Queue.Queue()
for _ in range(size):
t = Thread(self._queue)
self._pool.append(t)
QObject.connect(t, 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)
# coding: utf8
import sys
import urllib2
import traceback
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from taskpool import TaskPool, Task
class MyTask(Task):
# через конструктор передаем любые параметры
def __init__(self, url):
self.url = url
# метод, который будет вызван в потоке
def __call__(self):
source = urllib2.urlopen(self.url).read()
self.size = round(len(source) / 1024)
URLS = ['http://www.apple.com', 'http://www.yandex.ua', 'http://www.google.com', 'http://www.yahoo.com', 'http://www.microsoft.com', 'http://unknown-site.com']
class Main(QWidget):
def __init__(self):
QWidget.__init__(self)
self.layout = QVBoxLayout()
self.button = QPushButton('Start')
QObject.connect(self.button, SIGNAL('clicked()'), self.start)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
# создаем пул потоков, параметр - количество потоков
self.pool = TaskPool(6)
# метод будет вызван для каждой задачи. Вызван в главном потоке, поэтому можно обновлять GUI и т.д.
def callback(self, task):
# если задача в потоке "вылетит" с ошибкой, необработанное исключение
# будет перехвачено и записано в свойство error - type, value, traceback
if task.error:
print 'ERROR for URL %s' % task.url
traceback.print_exception(*task.error)
else:
print 'URL: %s SIZE: %d KB' % (task.url, task.size)
def start(self):
for url in URLS:
# создаем задачу
task = MyTask(url)
# кладем в пул задачу и необязательную функцию обратного вызова
self.pool.put(task, self.callback)
app = QApplication(sys.argv)
w = Main()
w.show()
sys.exit(app.exec_())
Отредактировано (Дек. 15, 2010 15:44:14)
Офлайн
Спасибо. Буду разбираться.
Офлайн