1na1
@1na1
Hello, world!

Как отправлять сигналы из отдельного потока PyQt5?

Всем привет!

Изучаю многопоточность в QT. В вопросах многопотока я новичок.

Задача: написать окно, которое при установке сетевого соединения не замораживается. При этом в случае потери соединения и при других сетевых событиях должна быть определенная реакция. Используя этот мануал я создал приложение для проверки функционала, код ниже.

Проблема: Если я запускаю задачу в отдельном потоке, ломается функционал сигналов и слотов. Само сетевое соединение выполняется, однако объект, запущенный в соседнем потоке никак об этом не сообщает. Сигнал не раздается, либо не слышится.

Вопрос: как мне поймать сигнал, который отправлен из другого потока?

Для примера максимально упростил код приложения

from PyQt5.QtNetwork import QTcpSocket
from PyQt5.QtCore import QThreadPool, QRunnable
from PyQt5.QtWidgets import QApplication


class Task(QRunnable):  # Задача, которая будет запускаться в отдельном потоке
    def __init__(self, socket):  # Передаем ссылку на объект класса QTcpSocket, через который будет установлено соединение
        super(Task, self).__init__()
        self.socket = socket  # Сохраняем ссылку на объект

    def run(self):  # Запустить обработку задачи
        self.socket.connected.emit()  # Сообщить об успешной установке соединения
        self.socket.disconnected.emit()  # Сообщить о разрыве соединения


socket = QTcpSocket()  # Создаем сокет
task = Task(socket)  # Передаем ссылку на объект сокета в задачу

socket.connected.connect(lambda: print('Connected'))  # Присоединяем обработчик к сигналу connected
socket.disconnected.connect(lambda: print('Disconnected'))  # Присоединяем обработчик к сигналу disconnected

# Ниже начинается магия

# Так работает - последовательно выводит сначала "Connected", потом "Disconnected"
#
# task.run()
#


# Так не работает - не выводит ничего - сиглалы теряются где-то по дороге.
#
thread_pool = QThreadPool()
thread_pool.start(task)
#

app = QApplication([])
app.exec_()
  • Вопрос задан
  • 579 просмотров
Пригласить эксперта
Ответы на вопрос 1
rewen
@rewen
#byrew
У меня получилось подобное сделать седующим образом : повесил декоратор на функцию , которая принимает сигнал, тогда основной поток остается работать в программе, когда второй выполняет функцию.
Используемая библиотека pyqt5
к примеру
def thread_my(my_func):
    def wrapper(*args, **kwargs):
       my_thread = threading.Thread(target=my_func, args=args, kwargs=kwargs)
       my_thread.start()
    return wrapper



    @thread_my
    def showDialog(self, true):
        print("PUST")
        cnt_list = []
        rng_contact_view_2 = self.contact_view_2.count()
        for x in range(rng_contact_view_2):
            cnt_list.append(self.contact_view_2.item(x).text())


        val_iter = 0
        for contact in cnt_list:
            val_iter += 1
            self.progress_bar(val_iter, len(cnt_list) + 1)
            bot_whatsapp().send_message(contact)
        driver.quit()
        self.progress_bar_clear()

# Вызов диалогового окна
self.btn_start.clicked.connect(self.showDialog)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы