Форум программистов, компьютерный форум, киберфорум
Python
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.76/21: Рейтинг темы: голосов - 21, средняя оценка - 4.76
0 / 0 / 0
Регистрация: 31.12.2015
Сообщений: 10
1

PyQt как получить сигнал из потока

20.01.2016, 01:05. Показов 3891. Ответов 8
Метки нет (Все метки)

у меня не получается получить сигнал из созданного потока.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# -*- coding: utf-8 -*-
import sys
from PyQt4              import QtCore , QtGui
import time
#================================================================
 
#================================================================
# поточный класс
class CWorker( QtCore.QThread ):
    def run(self):
        iCount = 0
        while iCount < 3 :
            iCount = iCount +1
            sData = u'[w'+str( iCount )+']'
            self.emit( QtCore.SIGNAL(u"sData(QString)") , sData )
            print u't+'
            time.sleep(1.5)
        self.emit( QtCore.SIGNAL(u"closed()") )
#================================================================
 
#================================================================
class CMaster( QtCore.QObject ):
    MySignal = QtCore.pyqtSignal(u'QString')
 
    def __init__(self , title = u'CBizScript' ):
        QtCore.QObject.__init__(self)
        self.mWorker = CWorker()
        # сигналы :
        self.connect( self.mWorker , QtCore.SIGNAL(u'sData(QString)') , self.gotWorkerMsg )
        self.MySignal.connect( self.gotWorkerMsg )
 
        self.mWorker.start()
 
    # получили сигнал
    def gotWorkerMsg(self , sText):
        print  u'(!)gotWorkerMsg : ' +sText
 
    # точка входа
    def main(self):
        i = 0
        while i < 7 :
            i = i +1
            print i
            time.sleep(1)
        print u'[end of program]'
        exit(0)
#================================================================
 
#================================================================
# передаем аргументы командной строки :
app = QtGui.QApplication( sys.argv )
mMain = CMaster()
mMain.main()
sys.exit( app.exec_() )             # результат работы
#================================================================
при запуске получают вот такой вывод в консоль :
1
t+
2
t+
3
4
t+
5
6
7
[end of program]

Process finished with exit code 0

Как правильно принимать сигналы?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2016, 01:05
Ответы с готовыми решениями:

Выполнение слота основного потока через сигнал второстепенного потока
Доброго времени суток! Вопрос следующий. В основном потоке создается кнопка и Qlabel class...

PyQt один сигнал на два слота
При переключении QComboBox'a нужно сделать два действия, которые осуществляются разными методами....

PyQt: подсоединить сигнал stateChanged к QCheckBox
Не могу подсоединить сигнал stateChanged для обработки нажатия (изменения состояния) QCheckBox. ...

Как передать сигнал из необьявленого потока?
Есть 2 класса потоков один называется Starter - управляет потоками, обьявляется в главном gui...

8
2730 / 2333 / 620
Регистрация: 19.03.2012
Сообщений: 8,832
20.01.2016, 07:06 2
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import sys
import time
import threading
 
from PyQt4 import QtGui, QtCore
 
 
def thread(my_func):
    """
    Запускает функцию в отдельном потоке
    """
    def wrapper(*args, **kwargs):
        my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs)
        my_thread.start()
    return wrapper
 
@thread
def processing(signal):
    """
    Эмулирует обработку (скачивание) каких-то данных
    """
    res = [i for i in 'hello']
    time.sleep(5)
    signal.emit(res)  # Посылаем сигнал в котором передаём полученные данные
 
 
class MyWidget(QtGui.QWidget):
    my_signal = QtCore.pyqtSignal(list, name='my_signal')
 
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.mainLayout = QtGui.QHBoxLayout()
        self.setLayout(self.mainLayout)
 
        self.button = QtGui.QPushButton("Emit your signal!", self)
        self.mainLayout.addWidget(self.button)
 
        # При нажатии на кнопку запускаем обработку данных
        self.button.clicked.connect(lambda: processing(self.my_signal))
 
        # Обработчик сигнала
        self.my_signal.connect(self.mySignalHandler, QtCore.Qt.QueuedConnection)
 
    def mySignalHandler(self, data):  # Вызывается для обработки сигнала
        print(data)
 
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MyWidget()
    window.show()
    app.exec_()
0
0 / 0 / 0
Регистрация: 31.12.2015
Сообщений: 10
20.01.2016, 12:23  [ТС] 3
Спасибо за ответ,
но похоже это не совсем то что мне нужно.
если я в своем примере буду наследовать мастер класс от QtGui.QWidget
и вызывать метод .show()
то и сигналы будут успешно приходить,
но мне необходимо работать без отрисовки окна.

вот небольшая модификация моего кода:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# -*- coding: utf-8 -*-
import sys
from PyQt4              import QtCore , QtGui
import time
#================================================================
 
#================================================================
# поточный класс
class CWorker( QtCore.QThread ):
    def run(self):
        iCount = 0
        while iCount < 3 :
            iCount = iCount +1
            sData = u'[w'+str( iCount )+']'
            self.emit( QtCore.SIGNAL(u"sData(QString)") , sData )
            print u't+'
            time.sleep(1.5)
        self.emit( QtCore.SIGNAL(u"closed()") )
#================================================================
 
#================================================================
class CMaster( QtGui.QWidget ):
    MySignal = QtCore.pyqtSignal(u'QString')
 
    def __init__(self , title = u'CBizScript' ):
        QtGui.QWidget.__init__(self)
        #-------------
        # * * * код для настройки окна :
        self.setGeometry(200, 200, 40, 50)
        self.mButton = QtGui.QPushButton( u'start' ,self)
        mHBox   = QtGui.QHBoxLayout()
        mHBox.addWidget( self.mButton )
        self.setLayout( mHBox )
        self.connect( self.mButton , QtCore.SIGNAL('clicked()') , self.onButton )
        #-------------
        self.mWorker = CWorker()
        # сигналы :
        self.connect( self.mWorker , QtCore.SIGNAL(u'sData(QString)') , self.gotWorkerMsg )
        self.MySignal.connect( self.gotWorkerMsg )
 
 
    def onButton(self):
        self.mWorker.start()
 
    # получили сигнал
    def gotWorkerMsg(self , sText):
        print  u'(!)gotWorkerMsg : ' +sText
 
    # точка входа
    def main(self):
        i = 0
        while i < 7 :
            i = i +1
            print i
            time.sleep(1)
        print u'[end of program]'
        exit(0)
#================================================================
 
#================================================================
# передаем аргументы командной строки :
app = QtGui.QApplication( sys.argv )
mMain = CMaster()
mMain.show()
sys.exit( app.exec_() )             # результат работы
#================================================================
и я получаю в консоле вот такой вывод :
(!)gotWorkerMsg : [w1]
t+
(!)gotWorkerMsg : [w2]
t+
(!)gotWorkerMsg : [w3]
t+

но это мне не подходит т.к. на экран отрисовывается окно
а если окно не отрисовывать то сигналы главный поток у меня не обрабатывает
0
2730 / 2333 / 620
Регистрация: 19.03.2012
Сообщений: 8,832
20.01.2016, 15:10 4
Цитата Сообщение от fox2019 Посмотреть сообщение
но мне необходимо работать без отрисовки окна.
Мой код ни как не завязан на каком-то графическом виджете, так что все что ты написал глупость.

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys
import time
import threading
 
from PyQt4 import QtGui, QtCore
 
 
def thread(my_func):
    """
    Запускает функцию в отдельном потоке
    """
    def wrapper(*args, **kwargs):
        my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs)
        my_thread.start()
    return wrapper
 
@thread
def processing(signal):
    """
    Эмулирует обработку (скачивание) каких-то данных
    """
    res = [i for i in 'hello']
    time.sleep(5)
    signal.emit(res)  # Посылаем сигнал в котором передаём полученные данные
 
 
class MyWidget(QtCore.QObject):
    my_signal = QtCore.pyqtSignal(list, name='my_signal')
 
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        processing(self.my_signal)
 
        # Обработчик сигнала
        self.my_signal.connect(self.mySignalHandler, QtCore.Qt.QueuedConnection)
 
    def mySignalHandler(self, data):  # Вызывается для обработки сигнала
        print('Работа завершена')
        print(data)
 
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MyWidget()
    app.exec_()
0
0 / 0 / 0
Регистрация: 31.12.2015
Сообщений: 10
20.01.2016, 16:02  [ТС] 5
Цитата Сообщение от alex925 Посмотреть сообщение
все что ты написал глупость
спасибо за конкретику очень помогло В другой раз вначале Гвидо спрошу а уж если он не знает то сразу к вам)

быть может и мой код сможете подредактировать что бы он заработал?
но только как то по проще,если возможно без декораторов, лямбда функций, на основе QThread, и под питон 2,7
0
2730 / 2333 / 620
Регистрация: 19.03.2012
Сообщений: 8,832
20.01.2016, 16:20 6
Цитата Сообщение от fox2019 Посмотреть сообщение
спасибо за конкретику очень помогло
Сообщение на столько же конкретное как и твое.
Цитата Сообщение от fox2019 Посмотреть сообщение
В другой раз вначале Гвидо спрошу а уж если он не знает то сразу к вам)
Попробуй

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# -*- coding: utf-8 -*-
import sys
import time
 
from PyQt4 import QtCore, QtGui
 
 
class CWorker(QtCore.QThread):
    def __init__(self, my_signal):
        super(CWorker, self).__init__()
        self.my_signal = my_signal
 
    def run(self):
        for i in range(3):
            data = u'[w' + str(i) + ']'
            self.my_signal.emit(data)
            print('t+')
            time.sleep(1.5)
        self.my_signal.emit('exit')
 
 
class CMaster(QtGui.QWidget):
    my_signal = QtCore.pyqtSignal(str)
 
    def __init__(self, title=u'CBizScript'):
        QtGui.QWidget.__init__(self)
 
        self.setGeometry(200, 200, 40, 50)
        self.mButton = QtGui.QPushButton('start', self)
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.mButton)
        self.setLayout(layout)
 
        self.connect(self.mButton, QtCore.SIGNAL('clicked()'), self.on_button)
 
        self.worker = CWorker(self.my_signal)
        self.my_signal.connect(self.got_worker_msg, QtCore.Qt.QueuedConnection)
 
    def on_button(self):
        self.worker.start()
 
    def got_worker_msg(self, sText):
        print(u'(!)gotWorkerMsg : ' + sText)
 
 
app = QtGui.QApplication(sys.argv)
main = CMaster()
main.show()
sys.exit(app.exec_())
0
0 / 0 / 0
Регистрация: 31.12.2015
Сообщений: 10
20.01.2016, 17:10  [ТС] 7
вот я переделал код что бы работал без окна :
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# -*- coding: utf-8 -*-
import sys
import time
 
from PyQt4 import QtCore, QtGui
 
 
class CWorker(QtCore.QThread):
    def __init__(self, my_signal):
        super(CWorker, self).__init__()
        self.my_signal = my_signal
 
    def run(self):
        for i in range(3):
            data = u'[w' + str(i) + ']'
            self.my_signal.emit(data)
            print('t+')
            time.sleep(1.5)
 
 
class CMaster(QtGui.QWidget):
    my_signal = QtCore.pyqtSignal(str)
 
    def __init__(self, title=u'CBizScript'):
        QtGui.QWidget.__init__(self)
 
        self.worker = CWorker(self.my_signal)
        self.my_signal.connect(self.got_worker_msg, QtCore.Qt.QueuedConnection)
 
    def main(self):
        self.worker.start()
        for i in range(7):
            print u'main ' + str(i)
            time.sleep(1)
 
    def got_worker_msg(self, sText):
        print(u'(!)gotWorkerMsg : ' + sText)
 
 
app = QtGui.QApplication(sys.argv)
main = CMaster()
main.main()
sys.exit(app.exec_())
вывод в консоли получился вот такой :
main 0
t+
main 1
t+
main 2
t+
main 3
main 4
main 5
main 6
(!)gotWorkerMsg : [w0]
(!)gotWorkerMsg : [w1]
(!)gotWorkerMsg : [w2]

выходит что оба потока работают параллельно
но главный поток не обрабатывает полученные сообщения пока выполняет какую либо работу.
причем если добавить exit(0) в конце функции main
Python
1
2
3
4
5
6
    def main(self):
        self.worker.start()
        for i in range(7):
            print u'main ' + str(i)
            time.sleep(1)
        exit(0)
то сообщения
(!)gotWorkerMsg : [w0]
(!)gotWorkerMsg : [w1]
(!)gotWorkerMsg : [w2]
вообще не будут обработанны
0
2730 / 2333 / 620
Регистрация: 19.03.2012
Сообщений: 8,832
20.01.2016, 17:34 8
Цитата Сообщение от fox2019 Посмотреть сообщение
но главный поток не обрабатывает полученные сообщения пока выполняет какую либо работу.
Естественно не обрабатывает, он занят выполнением другой функции.

Если хочешь параллельное выполнение 2 кусков кода, то оба запускай их в потоках, а главный поток, будет только дережировать ими.
0
0 / 0 / 0
Регистрация: 31.12.2015
Сообщений: 10
21.01.2016, 19:08  [ТС] 9
спасибо, разобрался.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.01.2016, 19:08

Как послать сигнал (самодельный) методом emit из потока в другой поток?
#include &quot;mainwindow.h&quot; #include &quot;ui_mainwindow.h&quot; MainWindow::MainWindow(QWidget *parent) : ...

Как из com порта получить сигнал?
Здравствуйте уважаемые форумчаны и форумчанки. Мне нужно из СОМ порта получить данные, но не...

Сигнал из другого потока
есть объект, который создается в главном потоке. у него есть сигнал. данныe в объект поступают из...

Может ли получить сигнал потомок от родителя, если сигнал: посылается всем (kill(0,SIGTERM) а потомок был добавлен в группу
Может ли получить сигнал потомок от родителя, если сигнал: посылается всем (kill(0,SIGTERM)) а...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru