Форум сайта python.su
Привет всем!
Пытаюсь сделать пример: http://www.commandprompt.com/community/pyqt/x3738 (Example 10-22. Python threads and a PyQt gui window). Вот он:
import sys, time
from threading import *
from qt import *
class TextThread(Thread):
def __init__(self, name, *args):
self.counter=0
self.name=name
apply(Thread.__init__, (self, ) + args)
def run(self):
while self.counter < 200:
print self.name, self.counter
self.counter = self.counter + 1
time.sleep(1)
class MainWindow(QMainWindow):
def __init__(self, *args):
apply(QMainWindow.__init__, (self,) + args)
self.editor=QMultiLineEdit(self)
self.setCentralWidget(self.editor)
self.thread1=TextThread("thread1")
self.thread2=TextThread("thread2")
self.thread1.start()
self.thread2.start()
def main(args):
app=QApplication(args)
win=MainWindow()
win.show()
app.connect(app, SIGNAL("lastWindowClosed()"),
app, SLOT("quit()"))
app.exec_loop()
if __name__=="__main__":
main(sys.argv)
import sys, time
from threading import *
from PyQt4 import QtCore, QtGui
class TextThread(Thread):
def __init__(self, name, *args):
self.counter=0
self.name=name
apply(Thread.__init__, (self, ) + args)
def run(self):
while self.counter < 200:
print self.name, self.counter
self.counter = self.counter + 1
time.sleep(1)
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
self.editor=QtGui.QMultiLineEdit(self)
self.setCentralWidget(self.editor)
self.thread1=TextThread("thread1")
self.thread2=TextThread("thread2")
self.thread1.start()
self.thread2.start()
def main(args):
app=QtGui.QApplication(args)
win=MainWindow()
win.show()
app.connect(app, SIGNAL("lastWindowClosed()"),
app, SLOT("quit()"))
app.exec_loop()
if __name__=="__main__":
main(sys.argv)
Отредактировано (Авг. 27, 2008 19:41:30)
Офлайн
from threading import * -> from threading import Thread # не делайте так больше
app.connect(app, SIGNAL(“lastWindowClosed()”), app, SLOT(“quit()”)) # это не нужно, приложение закроется автоматически
app.exec_loop() -> app.exec_()
QtGui.QMultiLineEdit(self) -> self.editor=QtGui.QTextEdit(self) # переименовали виджет
while self.counter < 200: -> while self.counter < 20:
и
time.sleep(1) -> time.sleep(0.1) # не выдержал таких пауз:)
import sys, time
from threading import Thread
from PyQt4 import QtCore, QtGui
class TextThread(Thread):
def __init__(self, name, *args):
self.counter=0
self.name=name
super(TextThread, self).__init__(*args)
#apply(Thread.__init__, (self, ) + args)
def run(self):
while self.counter < 20:
print self.name, self.counter
self.counter = self.counter + 1
time.sleep(0.1)
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
self.editor=QtGui.QTextEdit(self)
self.setCentralWidget(self.editor)
self.thread1=TextThread("thread1")
self.thread2=TextThread("thread2")
self.thread1.start()
self.thread2.start()
def main(args):
app=QtGui.QApplication(args)
win=MainWindow()
win.show()
app.exec_()
if __name__=="__main__":
main(sys.argv)
Отредактировано (Авг. 27, 2008 20:12:42)
Офлайн
Огромное спасибо!
А вы не подскажите пожалуйста, как сделать так, чтобы принт осуществлялся прямо в QTextEdit, а не в консоль ? Не пойму как из TextThread обратиться к тому, что в MainWindow …
Отредактировано (Авг. 28, 2008 11:40:41)
Офлайн
j2a уже давал примеры использования QThread, я бы советовал использовать их. А связать это всё можно сигналами, попробуйте сами разобраться, если не получится, пиши сюда:)
Офлайн
Я так понял надо использовал connect и emit …
Я с кнопками всякими в курсе как это делать, а вот с объектами этими не пойму, подскажите пожалуйста как сделать так чтобы вместо print, можно было сделать self.editor.append(self.name, self.counter) ?
Что-то типо
self.connect(TextThread, SIGNAL('s'), self.editor.append)
?
Офлайн
Пробуй! Направление верное, не получится, давай сюда свой вариант, может поправим…
Чтобы с сигналом передать строку, пиши так: SIGNAL('s(const QString)'), и когда будешь делать эмит, используй этот же синтаксис и передай в параметре строку.
Офлайн
Примерно понял как делать, жалуется на тип 1 аргумента от connect …
Источник: TextThread
Получатель: self.editor.append
Что передаём: name
Как то так?
import sys, time, os
from threading import Thread
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QObject, SIGNAL
class TextThread(Thread):
def __init__(self, name, *args):
self.counter=0
self.name=name
super(TextThread, self).__init__(*args)
#apply(Thread.__init__, (self, ) + args)
def run(self):
while self.counter < 20:
print self.name, self.counter
QtCore.QObject.emit(SIGNAL('s(const QString)'), name)
self.counter = self.counter + 1
time.sleep(0.1)
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
self.editor=QtGui.QTextEdit(self)
self.setCentralWidget(self.editor)
QObject.connect(TextThread, QtCore.SIGNAL('s(const QString)'), self.editor.append)
self.thread1=TextThread("thread1")
self.thread2=TextThread("thread2")
self.thread1.start()
self.thread2.start()
def main(args):
app=QtGui.QApplication(args)
win=MainWindow()
win.show()
app.exec_()
if __name__=="__main__":
main(sys.argv)
Отредактировано (Авг. 28, 2008 19:04:26)
Офлайн
Во-первых, надо переписать код под QThread: http://www.python.su/forum/viewtopic.php?id=2507
Во-вторых, коннектить надо не класс (TextThread), а его инстанс (self.thread1/2) и делать это после создания потоков, но перед их запуском.
Отредактировано (Авг. 28, 2008 19:47:01)
Офлайн
Уважаемый poltergeist, спасибо вам за ваши неоценимые советы по pyqt!
1) Переписал под QtThread
2) Вроде бы разобрался с коннектами, код работает без ошибок, но данные не попадают на editor :(
Видимо, что-то немного не так сделал по сигналам, будьте любезны если возможно подсказать в чём беда?
С уважением!
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QObject, SIGNAL
import sys, time
class QWorker(QtCore.QThread):
def __init__(self, name, *args):
QtCore.QThread.__init__(self, *args)
self.counter = 0
self.name = name
super(QWorker, self).__init__(*args)
self.emit(QtCore.SIGNAL('data_from_thread(const QString)'), name)
#self.emit(QtCore.SIGNAL("data_ready(PyQt_PyObject)"), name)
def run(self):
while self.counter<20:
#print self.name, self.counter
self.counter = self.counter + 1
time.sleep(0.1)
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
self.editor=QtGui.QTextEdit(self)
self.setCentralWidget(self.editor)
self.thread1=QWorker("thread1")
self.thread2=QWorker("thread2")
# сендер, сигнал, принимающий
self.connect(self.thread1, QtCore.SIGNAL('data_from_thread(const QString)'), self.editor.append)
def main(args):
app=QtGui.QApplication(args)
win=MainWindow()
win.show()
win.thread1.start()
win.thread2.start()
app.exec_()
if __name__=="__main__":
main(sys.argv)
Отредактировано (Авг. 30, 2008 17:46:46)
Офлайн
То что надо, все бы так спрашивали:)
1) self.emit(QtCore.SIGNAL('data_from_thread(const QString)'), name) надо делать в методе run() - это аналог print (по смыслу), который у вас уже присутствовал;
2) после QtCore.QThread.__init__(self, *args) не надо ещё раз вызывать инициализацию родительского класса;
3) добавил ещё один коннект ко второму потоку;
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QObject, SIGNAL
import sys, time
class QWorker(QtCore.QThread):
def __init__(self, name):
QtCore.QThread.__init__(self)
self.counter = 0
self.name = name
def run(self):
while self.counter<20:
self.emit(QtCore.SIGNAL('data_from_thread(const QString)'), self.name)
self.counter = self.counter + 1
time.sleep(0.1)
class MainWindow(QtGui.QMainWindow):
def __init__(self, *args):
apply(QtGui.QMainWindow.__init__, (self,) + args)
self.editor=QtGui.QTextEdit(self)
self.setCentralWidget(self.editor)
self.thread1=QWorker("thread1")
self.thread2=QWorker("thread2")
# сендер, сигнал, принимающий
self.connect(self.thread1, QtCore.SIGNAL('data_from_thread(const QString)'), self.editor.append)
self.connect(self.thread2, QtCore.SIGNAL('data_from_thread(const QString)'), self.editor.append)
def main(args):
app=QtGui.QApplication(args)
win=MainWindow()
win.show()
win.thread1.start()
win.thread2.start()
app.exec_()
if __name__=="__main__":
main(sys.argv)
Отредактировано (Авг. 30, 2008 18:56:56)
Офлайн