Помощь в инициализации потока основного окна и дополнительных рабочих потоков
Было нарисовано в PyQt5 основное окно, в котором есть 2 Qtextedit'a, в которые должны выводиться строки (своего рода лог) о результатах работы устройств которые работают через СОМ-порты, устройства 2 и они работают параллельно (каждый в своем потоке).
Без дестопной части, всё работает хорошо, а вот с ней, не работает ничего.
Прошу помощи в решении этой проблемы, в том числе и на мат. основе.
Код работы main прилагаю.
если нужно подробно рассказать о проекте, готов выйти в телеграмм, дискорд, куда угодно.
import reo_main_window
import dialog_adress
import scanclass
import time
import serial
import serial.tools.list_ports
import sys
from threading import Thread
"""
Функция "scanttyusb" сканирует порты и возвращает номера портов
к которым подключены нужные устройства
"""
def scan_ttyusb():
ports = list(serial.tools.list_ports.comports())
result = ""
for text in ports:
if 'Pcui' in text[1]:
txt = text[0]
result = result + txt + ','
device_port = result
return device_port.split(",")
"""
Функция "runing_scan" создает экземпляр класса помещая в него нужные значения переменных
"""
def runing_scan(number_port):
scan = scanclass.ScanningReo("serial_port", "date_from_cmd", "date_command", "name_freq", "name_dev")
print(number_port)
opn_srl_prt = scan.open_serial_port(number_port)
opn_srl_prt.close()
opn_srl_prt = scan.open_serial_port(number_port)
# print(opn_srl_prt)
id_dev = scan.device_identification(opn_srl_prt)
print(id_dev)
if "120" in id_dev:
ui.label_plate_1.setText(f"{id_dev}")
date_command = [f'"AT^SYSCFGEX\r"', "AT^NETSCAN\r",
f'"AT^SYSCFGEX=\r"', "AT^NETSCAN\r",
"STOP"
]
elif "821" in id_dev:
ui.label_plate_2.setText(f"{id_dev}")
date_command = [f'"AT^SYSCFGEX\r"', "AT^NETSCAN\r",
f'"AT^SYSCFGEX=\r"', "AT^NETSCAN\r",
"STOP"
]
for i in date_command:
if "SYSCFGEX" in i:
i = i.strip('"')
time.sleep(2)
while scan.send_comm(opn_srl_prt, i) == "STOP":
message_handler(id_dev, msg=date_command)
time.sleep(2)
"""
Функция "run_th" запускает потоки с экземплярами класса
"""
def run_th():
plate1 = scan_ttyusb()[0]
plate2 = scan_ttyusb()[1]
thread1 = Thread(target=runing_scan, args=[plate1])
thread2 = Thread(target=runing_scan, args=[plate2])
start = time.time()
thread1.start()
thread2.start()
thread1.join()
end = time.time()
print("Время работы потока 1: " + time.strftime("%M:%S", time.gmtime(end - start)))
thread2.join()
end2 = time.time()
print("Время работы потока 2: " + time.strftime("%M:%S", time.gmtime(end2 - start)))
"""
Функция "message_handler" обрабатывает поступающие сообщения и выводит их в ui.textEdit
"""
def message_handler(id_dev, msg):
if "120" in id_dev:
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 1")
if "Начат" or "Закончен" in msg:
ui.textEdit_plate_1.append(f"{msg}")
ui.textEdit_plate_1.append(f"{msg}")
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 2")
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 3")
if "821" in id_dev:
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 1")
if "Начат" or "Закончен" in msg:
ui.textEdit_plate_1.append(f"{msg}")
ui.textEdit_plate_1.append(f"{msg}")
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 2")
if "AT^NETSCAN" in msg:
ui.textEdit_plate_1.append("Начинаю сканирование 3")
return msg
if __name__ == '__main__':
# Создание приложения
app = reo_main_window.QtWidgets.QApplication(sys.argv)
# Создание формы главного окна и инициализация Ui
main_window = reo_main_window.QtWidgets.QMainWindow()
ui = reo_main_window.Ui_MainWindow()
ui.setupUi(main_window)
main_window.show()
main_window.setFixedSize(680, 572)
# Создание формы диалога внесения адреса и инициализация uid
dialog = dialog_adress.QtWidgets.QWidget()
uid = dialog_adress.Ui_Form_dialog_adress()
uid.setupUi(dialog)
# dialog.show()
dialog.setFixedSize(440, 161)
# Вызов кнопки "Старт"
ui.pushButton_start.clicked.connect(run_th)
# Запуск основного цикла
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я не могу проверить ваше приложение и не понимаю некоторых вещей.
Но предложу вам попробовать следующее:
import sys
#- import time
#- from threading import Thread
# ??? я не понимаю ваши импорты !!!!!!!!!!!!!!!!!!
# ??? import reo_main_window
# ??? import dialog_adress
from PyQt5 import QtWidgets, QtGui, QtCore
import scanclass # ?
import serial
import serial.tools.list_ports
class Thread(QThread):
# я предполагаю что вам надо что-то передавать из дополнительного
# потока что-то типа object(видимо это список - id_dev) и
# str (видимо какая-то строка - msg, типа "Начинаю сканирование 2") и
# str ('Plate 1' или 'Plate 2', на всякий случай, если надо будет)
# в основном потоке показывать откуда пришли данные
updateSignal = QtCore.pyqtSignal(object, str, str) # !!!
def __init__(self, plate, name_thread):
super().__init__()
self.number_port = plate
self.name_thread = name_thread
print(f'number_port = {self.number_port}; {self.name_thread}')
def run(self): # runing_scan(number_port):
scan = scanclass.ScanningReo(
"serial_port", "date_from_cmd",
"date_command", "name_freq", "name_dev")
print(self.number_port)
opn_srl_prt = scan.open_serial_port(self.number_port)
opn_srl_prt.close()
opn_srl_prt = scan.open_serial_port(self.number_port)
# print(opn_srl_prt)
id_dev = scan.device_identification(opn_srl_prt)
print(id_dev)
if "120" in id_dev:
#- ui.label_plate_1.setText(f"{id_dev}")
self.updateSignal.emit(id_dev, '120', self.name_thread) # !!! +++
date_command = [f'"AT^SYSCFGEX\r"', "AT^NETSCAN\r",
f'"AT^SYSCFGEX=\r"', "AT^NETSCAN\r",
"STOP"]
elif "821" in id_dev:
#- ui.label_plate_2.setText(f"{id_dev}")
self.updateSignal.emit(id_dev, '821', self.name_thread) # !!! +++
date_command = [f'"AT^SYSCFGEX\r"', "AT^NETSCAN\r",
f'"AT^SYSCFGEX=\r"', "AT^NETSCAN\r",
"STOP"]
for i in date_command:
if "SYSCFGEX" in i:
i = i.strip('"')
self.msleep(1000 * 2) # 2 сек.
while scan.send_comm(opn_srl_prt, i) == "STOP": # ?
message_handler(id_dev, msg=date_command)
#- time.sleep(2)
self.msleep(1000 * 2) # 2 сек.
def message_handler(id_dev, msg):
""" Функция "message_handler" обрабатывает поступающие сообщения
и выводит их в ui.textEdit
"""
if "120" in id_dev:
if "AT^NETSCAN" in msg:
#- ui.textEdit_plate_1.append("Начинаю сканирование 1")
self.updateSignal.emit(
id_dev, "120Начинаю сканирование `120` 1", self.name_thread) # !!! +++
if "Начат" or "Закончен" in msg:
#- ui.textEdit_plate_1.append(f"{msg}")
#- ui.textEdit_plate_1.append(f"{msg}")
self.updateSignal.emit(
id_dev, "120Начат or Закончен `120`", self.name_thread) # !!! +++
# ??? if "AT^NETSCAN" in msg:
# ??? ui.textEdit_plate_1.append("Начинаю сканирование 2")
# ??? if "AT^NETSCAN" in msg:
# ??? ui.textEdit_plate_1.append("Начинаю сканирование 3")
if "821" in id_dev:
if "AT^NETSCAN" in msg:
#- ui.textEdit_plate_1.append("Начинаю сканирование `821` 1")
self.updateSignal.emit(
id_dev, "821Начинаю сканирование `821` 1", self.name_thread) # !!! +++
if "Начат" or "Закончен" in msg:
#- ui.textEdit_plate_1.append(f"{msg}")
#- ui.textEdit_plate_1.append(f"{msg}")
self.updateSignal.emit(
id_dev, "821Начат or Закончен `821`", self.name_thread) # !!! +++
# ??? if "AT^NETSCAN" in msg:
# ??? ui.textEdit_plate_1.append("Начинаю сканирование 2")
# ??? if "AT^NETSCAN" in msg:
# ??? ui.textEdit_plate_1.append("Начинаю сканирование 3")
# ??? return msg
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# модуль Ui_MainWindow надо импортировать
# как-то так:
# from q1461951_name_ui import Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton_start.clicked.connect(self.run_th)
def run_th(self):
""" Функция "run_th" запускает потоки с экземплярами класса """
device_port = self.scan_ttyusb()
plate1 = device_port[0] # scan_ttyusb()[0]
plate2 = device_port[1] # scan_ttyusb()[1]
self.thread_1 = Thread(plate1, 'Plate 1')
self.thread_1.updateSignal.connect(self.update_thread)
self.thread_1.start()
self.thread_2 = Thread(plate2, 'Plate 2')
self.thread_2.updateSignal.connect(self.update_thread)
self.thread_2.start()
# thread1 = Thread(target=runing_scan, args=[plate1])
# thread2 = Thread(target=runing_scan, args=[plate2])
def update_thread(self, id_dev, plate, name_thread):
if name_thread == 'Plate 1':
if plate == '120':
self.label_plate_1.setText(f"{id_dev}")
elif plate[0:3] == '120':
self.textEdit_plate_1.append(plate[3:])
elif name_thread == 'Plate 2':
if plate == '821':
self.label_plate_2.setText(f"{id_dev}")
elif plate[0:3] == '821':
self.textEdit_plate_1.append(plate[3:])
def scan_ttyusb(self):
""" Функция "scan_ttyusb" сканирует порты и возвращает номера портов
к которым подключены нужные устройства
"""
ports = list(serial.tools.list_ports.comports())
result = ""
for text in ports:
if 'Pcui' in text[1]:
txt = text[0]
result = result + txt + ','
device_port = result
return device_port.split(",")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# Создание формы главного окна и инициализация Ui
# main_window = QtWidgets.QMainWindow()
# ui = Ui_MainWindow()
# ui.setupUi(main_window)
main_window = MainWindow()
main_window.resize(680, 572)
main_window.show()
# main_window.setFixedSize(680, 572)
# ??? # Создание формы диалога внесения адреса и инициализация uid dialog_adress
# ??? dialog = QtWidgets.QWidget()
# ??? uid = Ui_Form_dialog_adress()
# ??? uid.setupUi(dialog)
# ??? # dialog.show()
# ??? dialog.setFixedSize(440, 161)
# Вызов кнопки "Старт"
# ui.pushButton_start.clicked.connect(run_th)
sys.exit(app.exec_())