Найти - Пользователи
Полная версия: [PyQt4] особенности вывода в QTextBrowser
Начало » GUI » [PyQt4] особенности вывода в QTextBrowser
1
necrozyablo
Вот столкнулся с непонятным есть простой код

for i in range(5):
self.ui.log_frame_5.insertHtml('123')
self.ui.log_frame_5.insertHtml('<br>')
time.sleep(1)

log_frame_5 это QTextBrowser
Визуально строки ‘123’ выводится все вместе и через 5 секунд. А как сделать чтобы вывод происходил мгновенно?
По сути у меня сейчас получается выводить только когда завершается работа исполняемого кода.
truporez
Используйте qt-сигналы, либо питоновские очереди. Можно, конечно, вызывать QtGui.qApp.processEvents(), но так или иначе, таким образом как делаете вы, нормальной gui *не будет*. Лучше начните с изучения qt-примеров.
necrozyablo
truporez
Используйте qt-сигналы, либо питоновские очереди. Можно, конечно, вызывать QtGui.qApp.processEvents(), но так или иначе, таким образом как делаете вы, нормальной gui *не будет*. Лучше начните с изучения qt-примеров.
А нормальный это какой?

Просто по всяким кнопочкам у меня идёт срабатывание через сингалы, потом вызов функций. Вот в этих функциях сложные расчёты и данные берутся из баз. Всё выводил принтом в консоль, но вот решил в gui сделать окошечко.

Не подскажете линку на хорошие примеры по PyQT, а то в тех что я видел как раз делали как я…
truporez
На длительных операциях используйте генераторы, либо отдельные нити. Для визуализации процесса в QT есть QProgressDialog, доступ к нему из другого потока можно организовать либо через Queue, либо эмитить преварительно подписаные слоты.
А то как делали вы будет замораживать интерфейс, что не есть хорошо.
Если владеете языком вероятного противника - на этом форуме была тема с книгами по QT. Если нет - примеры из site-packages\PyQt4\examples\
Вот еще по русски _ttp://forum.script-coding.info/viewforum.php?id=6
necrozyablo
truporez
На длительных операциях используйте генераторы, либо отдельные нити. Для визуализации процесса в QT есть QProgressDialog, доступ к нему из другого потока можно организовать либо через Queue, либо эмитить преварительно подписаные слоты.
А то как делали вы будет замораживать интерфейс, что не есть хорошо.
Если владеете языком вероятного противника - на этом форуме была тема с книгами по QT. Если нет - примеры из site-packages\PyQt4\examples\
Вот еще по русски _ttp://forum.script-coding.info/viewforum.php?id=6
Почитал Rapid GUI Programming with Python and Qt

Как я понял правильно это главный тред это GUI, в нём прописать какие то сигналы и из него запускать всякие другие треды которые будут делать emit в главный тред. А поскольку emit дело быстрое он не будет задумываться. А QtGui.qApp.processEvents() это такой костыль который больше для одно поточных долгих приложений, который посылает всё что наработано в GUI?
truporez
В целом верно. Часто processEvents применяется для обработки событий при вызове QProgressDialog.
Схематично это выглядит так:
pd = MyProgressDialog(self) 
th = MyThread(self)
th.start()
while th.isRunning():
if pd.wasCanceled():
th.terminate()
break
QtGui.qApp.processEvents()
pd.close()
Если прогрессдиалог нежелателен, можно организовать работу через очередь(Queue) и timerEvent: нитка отправляет в очередь данные которые по таймеру форма выводит в gui.
necrozyablo
А можно ещё пару вопросов?
Я вот просто в общем не знаю как лучше реализовать т.к. похоже методов несколько
У меня ситуация с сервера я по шифрованному протоколу(т.е. напрямую данные сам брать не могу) в 2 окна получаю всякие данные о заказчиках и некоторые логи. Все эти данные я через pywin считываю и окнами формы также нормально уже управляю.

Собственно поскольку я не знаю в какой момент произойдёт обновления информации. Я решил создать Стековый тред в котором по таймеру каждую секунду идёт сигнал в 2 треда которые проверяют данные с окон(один с одного второй со второго). В этих тредах я считываю данные из окон и произвожу расчёты если что то нужно сделать то я записываю время когда это надо сделать и добовляю в очередь Стекового треда из которого по времени эти команды запускаются.

Вообще так нормально делать или я создавая свой Стековый тред пишу велосипед?
————
И ещё я не совсем понял как работает lock = QReadWriteLock() и self.mutex = QMutex() наверное сказывается не очень хорошее знание англ.
В примерах зачем то используют и то и то, а в документации написано что это конкурирующие методы?

И вот я пытаюсь сделать 2 раза подряд
self.Test.start()
self.Test.start()
Но срабатывает только первый, хотя если дождаться выполнения Test и тогда его запустить 2 раз то он тоже сработает.
Test это

class Test(QThread):
def __init__(self, lock, parent=None):
super(Test, self).__init__(parent)
self.lock = lock
self.mutex = QMutex()
self.num=parent.num

def method3(self):
self.mutex.lock();
self.num *= 5;
time.sleep(1.5)
self.num /= 4;
self.mutex.unlock();

def run(self):
self.method3()
self.emit(SIGNAL(“indexed(int)”), self.num)

Что интересно если сделать Test2 (копия Test только имя др) и запустить его одновременно то они нормально будут вместе выполнятся, но self.mutex.lock(); для переменной self.num не сработает. И получится что если взять за входное число 6 то будет 6*5*5/4/4, а не 6*lock(5/4)unlock*5/4
Складывается у меня чувство что всё работает как то не так как я думаю…
necrozyablo
Вот а с таким кодом всё нормально локается и анлокается и получается в конце из 6 число 8, а не 9
Заработало после того как я сделал через lock.lockForWrite()
        
self.Test.start()
self.Test2.start()
print self.num
class Test(QThread):

def __init__(self, lock, parent=None):
super(Test, self).__init__(parent)
self.lock = lock
self.mutex = QMutex()
self.num=parent.num
print 'init test qthread'

def method3(self):

self.mutex.lock();

try:
self.lock.lockForWrite()
self.num[0] *= 5;
time.sleep(1.5)
self.num[0] /= 4;
finally:
self.lock.unlock()

self.mutex.unlock();


def run(self):
self.method3()
self.emit(SIGNAL("indexed(int)"), self.num[0])


class Test2(QThread):

def __init__(self, lock, parent=None):
super(Test2, self).__init__(parent)
self.lock = lock
self.stopped = False
self.mutex = QMutex()
self.num=parent.num

def method3(self):

print 'method3',self.num[0]
try:
self.lock.lockForWrite()
self.num[0] *= 5;
time.sleep(1.5)
self.num[0] /= 4;
finally:
self.lock.unlock()
print 'method3',self.num[0]
self.mutex.unlock();


def run(self):
self.method3()
self.emit(SIGNAL("indexed(int)"), self.num[0])
Я вот одного понять не могу почему я 2 раза подряд не могу заюзать self.Test.start()
pasaranax
Не понял, а зачем вызывать метод start у класса Test, а не у его экземпляра?
necrozyablo
pasaranax
Не понял, а зачем вызывать метод start у класса Test, а не у его экземпляра?
Ну вообще там по коду у меня так
from functions import Test

class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.lock = QReadWriteLock()
self.num=[6,8]
self.Test = Test(self.lock, self)
self.Test2 = Test2(self.lock, self)
self.connect(self.Test, SIGNAL("indexed(int)"), self.log_frame_deb3)
self.connect(self.ui.DebugButton, QtCore.SIGNAL("clicked()"), self.log_frame_deb)

def log_frame_deb3(self, fstatus):

self.num[0]=fstatus

def log_frame_deb(self):

self.Test.start()
#self.Test.start()
self.Test2.start()
print self.num
Нажимаю на DebugButton срабатывает log_frame_deb в нём у меня запускаются Threds Test и Test2 они делают emit ‘indexed(int)’ в log_frame_deb3
Нить Test я постом выше писал.
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