Уведомления

Группа в Telegram: @pythonsu

#1 Май 11, 2015 14:43:48

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2749
Репутация: +  184  -
Профиль   Отправить e-mail  

PyQT и многопоточность

http://python.su/forum/topic/24662/?page=2#post-130903



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#2 Май 11, 2015 15:22:24

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

Переписал по Вашему примеру.

import time
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QDesktopWidget
from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit, QGridLayout, QCheckBox
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QPixmap,QImage
#from threading import Thread #Потоки
class Main_Window(QMainWindow):
    def __init__(self):
        super(Main_Window,self).__init__()
        self.initUI()
        self.t = MyThread()
        QtCore.QObject.connect(self.t, QtCore.SIGNAL("message(str)"), self.setStatusBar)
        self.t.start()
    def initUI(self):
        self.statusBar().showMessage('Ready')
    #Отображаем текст в статусбаре
    def setStatusBar(self,text):
        self.statusBar().showMessage(str(text))
class Main_Widget(QWidget):
    def __init__(self):
        super(Main_Widget,self).__init__()
class MyThread(QtCore.QThread):
    def __init__(self):
         QtCore.QThread.__init__(self)
    def run(self):
        time.sleep(2)
        i = 0
        while True:
            text = str(i)
            i = i+1
            #Тут надо как-то вызвать смену текста статусбара
            self.emit(QtCore.SIGNAL("message(str)"), text)
            time.sleep(2)
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Main_Window()
    widget = Main_Widget()
    window.setCentralWidget(widget)
    window.show()
    #window.connect(QtCore.pyqtSignal("message()"),window.setStatusBar)
    sys.exit(app.exec_())
Даже QThread начал использовать
Всеравно ругается вот так:
Traceback (most recent call last):
  File "<string>", line 420, in run_nodebug
  File "D:\MyFiles\tests\1.py", line 58, in <module>
    window = Main_Window()
  File "D:\MyFiles\tests\1.py", line 26, in __init__
    QtCore.QObject.connect(self.t, QtCore.SIGNAL("message(str)"), self.setStatusBar)
AttributeError: type object 'QObject' has no attribute 'connect'
так же ругается и в другом месте
Traceback (most recent call last):
  File "D:\MyFiles\tests\1.py", line 52, in run
    self.emit(QtCore.SIGNAL("message(str)"), text)
AttributeError: 'MyThread' object has no attribute 'emit'



Win7 + Python3.3 + PyScripter

Отредактировано admiral (Май 11, 2015 15:27:26)

Офлайн

#3 Май 11, 2015 15:31:53

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

Блина, да что же это за система такая…
Даже просто сменить строку статусбара из другого потока не получается…



Win7 + Python3.3 + PyScripter

Офлайн

#4 Май 11, 2015 15:59:51

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2749
Репутация: +  184  -
Профиль   Отправить e-mail  

PyQT и многопоточность

# coding: utf-8
import sys
import PySide.QtGui as QtGui
import PySide.QtCore as QtCore
class Main_Window(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.statusBar().showMessage('Ready')
        self.t = MyThread()
        self.connect(self.t, QtCore.SIGNAL("message(PyObject)"), self.setStatusText)
        self.t.start()
    def setStatusText(self, text):
        self.statusBar().showMessage(text)
class MyThread(QtCore.QThread):
    def __init__(self):
         QtCore.QThread.__init__(self)
    def run(self):
        QtCore.QThread.msleep(2000)
        i = 0
        while True:
            text = str(i)
            i = i+1
            #Тут надо как-то вызвать смену текста статусбара
            self.emit(QtCore.SIGNAL("message(PyObject)"), text)
            QtCore.QThread.msleep(2000)
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = Main_Window()
    window.show()
    sys.exit(app.exec_())



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Отредактировано Rodegast (Май 11, 2015 16:01:28)

Офлайн

#5 Май 11, 2015 16:40:29

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

Спасибо. PySide у меня не установлен. И, как я понял, для PyQt5 не подходит код. Все равно ругается.
Но наконец-то я нашел внятное объяснение как делать сигналы вот тут.
Оказывается нужно сделать отдельный класс с наследованием от QObject, в нем прописать сигнал. И только потом уже можно к этому сигналу делать connect.
Вот в каком случае у меня заработало:

import time
from PyQt5 import QtCore
from PyQt5.QtCore import Qt, QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QDesktopWidget
from PyQt5.QtWidgets import QMainWindow, QLabel, QLineEdit, QGridLayout, QCheckBox
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QPixmap,QImage
from threading import Thread #Потоки
class Main_Window(QMainWindow):
    def __init__(self):
        super(Main_Window,self).__init__()
        self.initUI()
    def initUI(self):
        self.statusBar().showMessage('Ready')
    #Отображаем текст в статусбаре
    def setStatusBar(self,text):
        self.statusBar().showMessage(str(text))
class Main_Widget(QWidget):
    def __init__(self):
        super(Main_Widget,self).__init__()
class MyThread(Thread):
    def __init__(self,f):
        Thread.__init__(self)
        self.f = f
    def run(self):
        time.sleep(2)
        i = 0
        while True:
            text = str(i)
            i = i+1
            #Тут надо как-то вызвать смену текста статусбара
            self.f.message.emit(text)
            time.sleep(2)
class foo(QObject):
    message = pyqtSignal(str)
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = Main_Window()
    widget = Main_Widget()
    window.setCentralWidget(widget)
    window.show()
    f=foo()
    f.message.connect(window.setStatusBar)
    t = MyThread(f)
    t.start()
    sys.exit(app.exec_())



Win7 + Python3.3 + PyScripter

Офлайн

#6 Май 12, 2015 02:40:57

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

PyQT и многопоточность

Вот заготовка, которая работает для PyQt4

#!/usr/bin/env python3
 
from PyQt4 import QtGui, QtCore
import sys
import time
 
class MainWindow(QtGui.QMainWindow):
 
    def __init__(self):
        super().__init__()
        self.init_ui()
 
    def init_ui(self):
 
        self.thread = Thread(self)
        self.thread.message[str].connect(self.change_status)
        self.thread.start()
 
        self.statusBar().showMessage('Ready')
        self.show()
 
    def change_status(self, text):
        self.statusBar().showMessage(text)
 
class Thread(QtCore.QThread):
 
    message = QtCore.pyqtSignal(str)
          
    def run(self):
        while True:
            n = int(time.time()) % 10
            self.message.emit(str(n))
            time.sleep(1)
 
def main():
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())
 
if __name__ == '__main__':
    main()

Попробовал поставить PyQt5; короче, не поставилось. Через pip3 тянутся какие-то экзешники виндовые, а из исходников - проблема с qmake. Сырая установка, причём там у них не setup.py, как должно быть, а какой-то configure.py.

Можешь попробовать ещё добавить QObject к базовым классам потока.
class Thread(QtCore.QThread, QtCore.QObject):

admiral
Вот в каком случае у меня заработало:
Слот у тебя неправильно написан. Приходит текст, то есть уже строка, а ты строку снова делаешь строкой.



Отредактировано py.user.next (Май 12, 2015 02:47:47)

Офлайн

#7 Май 12, 2015 07:51:25

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

py.user.next
Слот у тебя неправильно написан. Приходит текст, то есть уже строка, а ты строку снова делаешь строкой.
Это я для надежности. А то в питоне с переменной можно делать все что угодно, а статусбар только строку может принимать. Ничего же страшного? Или стоит убрать преобразование в строку?



Win7 + Python3.3 + PyScripter

Офлайн

#8 Май 12, 2015 07:55:48

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

Блина, буду наверное кодить на PyQT4, а то каждый раз какие-то проблемы, а в инете большинство примеров для PyQT4 и, как оказалось, не так-то просто их переделать.



Win7 + Python3.3 + PyScripter

Офлайн

#9 Май 12, 2015 08:38:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9873
Репутация: +  853  -
Профиль   Отправить e-mail  

PyQT и многопоточность

admiral
А то в питоне с переменной можно делать все что угодно
Она должна выпасть, если что-то не то подаётся.

admiral
Или стоит убрать преобразование в строку?
Снаружи нужно преобразовывать.

admiral
Это я для надежности. :)
Функция становится надёжнее тогда, когда она не делает ничего лишнего - занимается только своим делом. (Функциональная прочность модуля.)



Отредактировано py.user.next (Май 12, 2015 08:38:51)

Офлайн

#10 Май 13, 2015 12:36:38

admiral
Зарегистрирован: 2013-12-23
Сообщения: 33
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT и многопоточность

py.user.next
Вот заготовка, которая работает для PyQt4
Поставил PyQT4 - заработала без проблем и ошибок. И без лишних созданий классов. Спасибо.



Win7 + Python3.3 + PyScripter

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version