@Flipzy
Веб-разработчик

Как в PyQt исправить ошибку?

У меня есть 3 файла:
main.py
import socket
import re
import queue

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

def Connect_to_controller(data_queue):
    host = '10.55.6.170'
    port = 23

    try:
        client_socket.connect((host, port))
        print("Успешно подключено")

        while True:
            response = client_socket.recv(1440)
            print(f"Принят ответ: {response.decode()}")
            data_to_send = "Ваши данные для контроллера"
            send_data_to_controller(data_to_send)
            data = extract_data(response)
            print(data)
            data_queue.put(data)

    except Exception as e:
        print(f"Произошла ошибка при подключении или обмене данными: {e}")

    finally:
        client_socket.close()
        
def send_data_to_controller(data):
    try:
        client_socket.send(data.encode("utf-8"))  # Здесь data - это ваша строка данных для отправки
        print("Данные успешно отправлены")
    except Exception as e:
        print(f"Произошла ошибка при отправке данных: {e}")

def extract_data(response):
    data = {}
    response = response.decode("utf-8")
    lines = response.split('\n')
    for line in lines:
        match = re.match(r'FCTST_(.*?),(.+)', line)
        if match:
            key = match.group(1)
            value = match.group(2)
            if key == 'UID':
                key = 'UID'
            data[key] = value
    return data


interface.py
from main import client_socket
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QLabel, QWidget, QLineEdit, QDialog, QPushButton
from PyQt5.QtCore import pyqtSignal


class FactoryDialog(QDialog):
    factory_signal = pyqtSignal(str, str, str)
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Настройки завода')
        
        layout = QVBoxLayout()
        
        self.factory_label = QLabel('Завод:')
        self.operator_label = QLabel('Оператор:')
        self.serial_start_label = QLabel('Начало серийного номера (UInt32):')
        
        self.factory_input = QLineEdit()
        self.operator_input = QLineEdit()
        self.serial_start_input = QLineEdit()
        
        self.run_button = QPushButton('Запустить')
        self.run_button.clicked.connect(self.on_run_button_clicked)
        
        layout.addWidget(self.factory_label)
        layout.addWidget(self.factory_input)
        layout.addWidget(self.operator_label)
        layout.addWidget(self.operator_input)
        layout.addWidget(self.serial_start_label)
        layout.addWidget(self.serial_start_input)
        layout.addWidget(self.run_button)
        
        self.setLayout(layout)

    def on_run_button_clicked(self):
        factory = self.factory_input.text()
        operator = self.operator_input.text()
        serial_start = self.serial_start_input.text()
        
        self.close()
        self.factory_signal.emit(factory, operator, serial_start)

class TCP_Checker_Window(QMainWindow):
    update_signal = pyqtSignal(dict)  # Определите сигнал как статический атрибут класса

    def __init__(self):
        super().__init__()
        self.setWindowTitle('TCP Checker')
        
        self.central_widget = QWidget(self)
        self.setCentralWidget(self.central_widget)
        
        layout = QVBoxLayout()

        self.labels = {
            'UID': QLabel('UID:'),
            'SPI_FLASH': QLabel('SPI_FLASH:'),
            'ETHERNET': QLabel('ETHERNET:'),
            'GSM_SIM1': QLabel('GSM_SIM1:'),
            'GSM_SIM2': QLabel('GSM_SIM2:'),
            'GNSS': QLabel('GNSS:'),
            'CAN': QLabel('CAN:'),
            'RTC': QLabel('RTC:')
        }

        label_stylesheet = """
            QLabel {
                font-family: Arial;
                font-size: 30px;
                color: #000;
                margin-left: 25px; /* Отступы */
            }
        """
        factory_signal = pyqtSignal(str, str, str)

    def __init__(self):
        super().__init__()
        self.setWindowTitle('TCP Checker')
        
        self.central_widget = QWidget(self)
        self.setCentralWidget(self.central_widget)
        
        layout = QVBoxLayout()

        self.labels = {
            'UID': QLabel('UID:'),
            'SPI_FLASH': QLabel('SPI_FLASH:'),
            'ETHERNET': QLabel('ETHERNET:'),
            'GSM_SIM1': QLabel('GSM_SIM1:'),
            'GSM_SIM2': QLabel('GSM_SIM2:'),
            'GNSS': QLabel('GNSS:'),
            'CAN': QLabel('CAN:'),
            'RTC': QLabel('RTC:'),
            'Factory': QLabel('Завод:'),
            'Operator': QLabel('Оператор:'),
            'SerialStart': QLabel('Начало серийного номера (UInt32):')
        }

        label_stylesheet = """
            QLabel {
                font-family: Arial;
                font-size: 30px;
                color: #000;
                margin-left: 25px;
            }
        """
        for key, value in self.labels.items():
            value.setStyleSheet(label_stylesheet)
            layout.addWidget(value)

        self.factory_input = QLineEdit()
        self.operator_input = QLineEdit()
        self.serial_start_input = QLineEdit()

        layout.addWidget(self.factory_input)
        layout.addWidget(self.operator_input)
        layout.addWidget(self.serial_start_input)

        self.central_widget.setLayout(layout)
        
    def closeEvent(self, event):
        # Закрытие сокета при закрытии окна
        try:
            client_socket.close()
        except Exception as e:
            print(f"Произошла ошибка при закрытии сокета: {e}")

        event.accept()

    def update_text_fields(self, data):
        for key, value in data.items():
            if key in self.labels:
                self.labels[key].setText(f'{key}: {value}')


app.py
import sys
import threading
import queue
from PyQt5.QtWidgets import QApplication, QDialog
from interface import TCP_Checker_Window, FactoryDialog
from main import Connect_to_controller
from PyQt5.QtCore import QTimer

app = QApplication(sys.argv)

def create_factory_dialog():
    factory_dialog = FactoryDialog()
    if factory_dialog.exec_() == QDialog.Accepted:
        create_tcp_checker_window(factory_dialog)

def create_tcp_checker_window(factory_dialog):
    window = TCP_Checker_Window()
    window.resize(800, 600)

    factory = factory_dialog.factory_input.text()
    operator = factory_dialog.operator_input.text()
    serial_start = factory_dialog.serial_start_input.text()

    window.factory_input.setText(factory)
    window.operator_input.setText(operator)
    window.serial_start_input.setText(serial_start)
    window.show()

    labels = window.labels

    data_queue = queue.Queue()

    controller_thread = threading.Thread(target=Connect_to_controller, args=(data_queue,))
    controller_thread.start()

    def update_interface(labels):
        while True:
            data = data_queue.get()
            window.update_text_fields(data)

    update_thread = threading.Thread(target=update_interface, args=(labels))
    update_thread.start()

    update_timer = QTimer()
    update_timer.timeout.connect(app.processEvents)
    update_timer.start(100)

if __name__ == '__main__':
    create_factory_dialog()
    sys.exit(app.exec_())


Объясняю логику проги:
При запуске открывается FactoryDialog, в нём вводятся некоторые данные и нажимается кнопка "Запустить". После нажатия кнопки, окно FactoryDialog закрывается и открывается TCP_Checker_Window и все соответствующие ему процессы. При этом информация, которую внёс пользователь на прошлом окне добавляется в лейблы и отображается в новом окне.

Суть проблемы:
После нажатия на кнопку "Запустить" прога закрывается и окно TCP_Checker_Window не открывается
  • Вопрос задан
  • 41 просмотр
Решения вопроса 1
@Flipzy Автор вопроса
Веб-разработчик
Ушёл от системы в несколько окон, сделал обновление интерфейса одного окна, в зависимости от того, какой класс наследуется, а в обработчик события кнопки прикрутил динамический импорт нужного метода
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы