Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 27, 2008 19:33:38

mario
От:
Зарегистрирован: 2007-08-04
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Привет всем!
Пытаюсь сделать пример: 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)
Пытаюсь перенести его на PyQt4, пожалуйста подскажите в чём ошибка?
Вот переделанное:

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)

Офлайн

#2 Авг. 27, 2008 20:09:49

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

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)

Офлайн

#3 Авг. 28, 2008 11:16:07

mario
От:
Зарегистрирован: 2007-08-04
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Огромное спасибо!

А вы не подскажите пожалуйста, как сделать так, чтобы принт осуществлялся прямо в QTextEdit, а не в консоль ? Не пойму как из TextThread обратиться к тому, что в MainWindow …



Отредактировано (Авг. 28, 2008 11:40:41)

Офлайн

#4 Авг. 28, 2008 12:47:48

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

j2a уже давал примеры использования QThread, я бы советовал использовать их. А связать это всё можно сигналами, попробуйте сами разобраться, если не получится, пиши сюда:)



Офлайн

#5 Авг. 28, 2008 17:49:54

mario
От:
Зарегистрирован: 2007-08-04
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Я так понял надо использовал connect и emit …
Я с кнопками всякими в курсе как это делать, а вот с объектами этими не пойму, подскажите пожалуйста как сделать так чтобы вместо print, можно было сделать self.editor.append(self.name, self.counter) ?

Что-то типо
self.connect(TextThread, SIGNAL('s'), self.editor.append)

?



Офлайн

#6 Авг. 28, 2008 18:27:48

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Пробуй! Направление верное, не получится, давай сюда свой вариант, может поправим…

Чтобы с сигналом передать строку, пиши так: SIGNAL('s(const QString)'), и когда будешь делать эмит, используй этот же синтаксис и передай в параметре строку.



Офлайн

#7 Авг. 28, 2008 19:04:00

mario
От:
Зарегистрирован: 2007-08-04
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Примерно понял как делать, жалуется на тип 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)

Офлайн

#8 Авг. 28, 2008 19:43:10

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Во-первых, надо переписать код под QThread: http://www.python.su/forum/viewtopic.php?id=2507
Во-вторых, коннектить надо не класс (TextThread), а его инстанс (self.thread1/2) и делать это после создания потоков, но перед их запуском.



Отредактировано (Авг. 28, 2008 19:47:01)

Офлайн

#9 Авг. 30, 2008 17:46:27

mario
От:
Зарегистрирован: 2007-08-04
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

Уважаемый 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)

Офлайн

#10 Авг. 30, 2008 18:52:06

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Пример PyQt4

То что надо, все бы так спрашивали:)

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)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version