Найти - Пользователи
Полная версия: Пример PyQt4
Начало » GUI » Пример PyQt4
1 2
mario
Привет всем!
Пытаюсь сделать пример: 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)
poltergeist
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)
mario
Огромное спасибо!

А вы не подскажите пожалуйста, как сделать так, чтобы принт осуществлялся прямо в QTextEdit, а не в консоль ? Не пойму как из TextThread обратиться к тому, что в MainWindow …
poltergeist
j2a уже давал примеры использования QThread, я бы советовал использовать их. А связать это всё можно сигналами, попробуйте сами разобраться, если не получится, пиши сюда:)
mario
Я так понял надо использовал connect и emit …
Я с кнопками всякими в курсе как это делать, а вот с объектами этими не пойму, подскажите пожалуйста как сделать так чтобы вместо print, можно было сделать self.editor.append(self.name, self.counter) ?

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

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

Чтобы с сигналом передать строку, пиши так: SIGNAL('s(const QString)'), и когда будешь делать эмит, используй этот же синтаксис и передай в параметре строку.
mario
Примерно понял как делать, жалуется на тип 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)
poltergeist
Во-первых, надо переписать код под QThread: http://www.python.su/forum/viewtopic.php?id=2507
Во-вторых, коннектить надо не класс (TextThread), а его инстанс (self.thread1/2) и делать это после создания потоков, но перед их запуском.
mario
Уважаемый 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)
poltergeist
То что надо, все бы так спрашивали:)

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)
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