Вылетает приложение pyqt при добавлении элементов treewidget

Пожалуйста, помогите быстрее, проект уже завтра надо сдать!

Делаю проект на pyqt6 - файловый сервер. Мой сервер возвращает клиенту строку вида:

[{"вложенная папка1": ["файл1", "файл2"]}, {"вложенная папка2": ["файл1", "файл2"], "файл1", "файл2"]

Клиент запрашивает файлы с сервера с помощью команды "FILES GET", и записывает результат в список, чтобы потом добавить все элементы в treewidget. Вот функция, которая крашит программу:

def make_tree_objects(self, objects: list[any], main: QTreeWidgetItem):
    for i in objects:
        if type(i) == str:
            main.addChild(QTreeWidgetItem([i]))
        else:
            t = list(i.items())
            print(t[0][0])
            temp = QTreeWidgetItem([t[0][0], ])
            self.make_tree_objects(t[0][1], temp)
            main.addChild(temp)

def make_request(self):
    self.sock.sendall(bytes("FILES GET", "utf-8"))
    resp = str(self.sock.recv(1024), "utf-8")
    get_files_trees = []
    t = exec(f"self.get_files_trees = {resp}")
    self.items = []
    self.main_files = QTreeWidgetItem(["files"])
    self.make_tree_objects(self.get_files_trees, self.main_files)
    self.items.append(self.main_files)
    print(self.items)
    self.files_tree.insertTopLevelItems(0, self.items)

приложение просто зависает и вылетает.

Полный код приложения:

import sys
from PyQt6 import uic
from PyQt6.QtCore import QThread, pyqtSignal
from PyQt6.QtWidgets import QApplication, QMainWindow, QTreeWidgetItem, QMessageBox
import socketserver
import multiprocessing
import socket


class MainForm(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi('untitled1.ui', self)
        self.connectButton.clicked.connect(self.connect)
        self.command.editingFinished.connect(self.send_command)

        self.files_tree.setColumnCount(1)
        self.files_tree.setHeaderLabels(["File or directory"])

        self.commandstd = []

    def send_command(self):
        self.commandstd.append(self.command.text())

    def perm_error(self):
        QMessageBox.critical(
            self,
            "Oh dear!",
            "Something went very wrong.",
            buttons=QMessageBox.StandardButton.Ok,
            defaultButton=QMessageBox.StandardButton.Ok,
        )
        pass

    def connect(self):
        print("eeew")
        print(self.connect_start)
        self.th_connect = MultiQtThreadedConnect()
        self.th_connect.signal.connect(self.connect_start)
        self.th_connect.start()

    def connect_start(self):
        print("Socket started")
        adr = self.adress.text()
        usr = self.username.text()
        pas = self.password.text()
        prt = self.port.text()
        print(adr, usr, pas, prt)
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self.sock:
            self.sock.connect((adr, int(prt)))
            print(("\n"*100) + self.username.text())
            print(f"""HELLO {f'login={self.username.text()}' if self.username.text() not in ['', ' ', None] else ''} {f'password={self.password.text()}' if self.password.text() not in ['', ' ', None] else ''}""")
            self.sock.sendall(bytes(f"""HELLO {f'login={self.username.text()}' if self.username.text() not in ['', ' ', None] else ''} {f'password={self.password.text()}' if self.password.text() not in ['', ' ', None] else ''}""", "utf-8"))

            received = str(self.sock.recv(1024), "utf-8")
            self.command_log.insertPlainText(received + "\n")
            print(received)
            old_lst = []
            if "HELLO" not in received:
                QMessageBox.critical(
                    self,
                    "Oh dear!",
                    "Something went very wrong.",
                    buttons=QMessageBox.StandardButton.Ok,
                    defaultButton=QMessageBox.StandardButton.Ok,
                )
                return
            self.make_request()

            while True:
                for i in self.commandstd:
                    self.sock.sendall(bytes(str(i), "utf-8"))
                    rec = self.sock.recv(1024)
                    self.command_log.insertPlainText(str(rec, "utf-8"))
                    self.commandstd.remove(i)
    def run(self):
        self.label.setText("OK")

    def make_tree_objects(self, objects: list[any], main: QTreeWidgetItem):
        for i in objects:
            if type(i) == str:
                print(QTreeWidgetItem([i]))
                main.addChild(QTreeWidgetItem([i]))
            else:
                t = list(i.items())
                print(QTreeWidgetItem([t[0][0], ]))
                temp = QTreeWidgetItem([t[0][0], ])
                self.make_tree_objects(t[0][1], temp)
                main.addChild(temp)

    def make_request(self):
        self.sock.sendall(bytes("FILES GET", "utf-8"))
        resp = str(self.sock.recv(1024), "utf-8")
        get_files_trees = []
        print(resp)
        t = exec(f"self.get_files_trees = {resp}")
        self.items = []
        self.main_files = QTreeWidgetItem(["files"])
        self.make_tree_objects(self.get_files_trees, self.main_files)
        self.items.append(self.main_files)
        print("wef")
        print(self.items)
        self.files_tree.insertTopLevelItems(0, self.items)


class Connector(socketserver.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()
        print("Received from {}:".format(self.client_address[0]))
        print(self.data)
        self.request.sendall(self.data.upper())


class MultiQtThreadedConnect(QThread):
    signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.flag = True
        self.i = 1

    def run(self):
        self.signal.emit()

    def stop(self):
        self.flag = False


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainForm()
    ex.show()
sys.exit(app.exec())

untitled1.ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1121</width>
    <height>623</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Filecloud</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QFrame" name="frame">
    <property name="geometry">
     <rect>
      <x>720</x>
      <y>0</y>
      <width>401</width>
      <height>131</height>
     </rect>
    </property>
    <property name="frameShape">
     <enum>QFrame::StyledPanel</enum>
    </property>
    <property name="frameShadow">
     <enum>QFrame::Raised</enum>
    </property>
    <widget class="QLineEdit" name="adress">
     <property name="geometry">
      <rect>
       <x>70</x>
       <y>10</y>
       <width>161</width>
       <height>20</height>
      </rect>
     </property>
     <property name="inputMask">
      <string>009\.009\.009\.009</string>
     </property>
    </widget>
    <widget class="QLineEdit" name="username">
     <property name="geometry">
      <rect>
       <x>70</x>
       <y>40</y>
       <width>161</width>
       <height>20</height>
      </rect>
     </property>
    </widget>
    <widget class="QLineEdit" name="password">
     <property name="geometry">
      <rect>
       <x>70</x>
       <y>70</y>
       <width>161</width>
       <height>20</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="connectButton">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>100</y>
       <width>75</width>
       <height>23</height>
      </rect>
     </property>
     <property name="text">
      <string>Connect</string>
     </property>
    </widget>
    <widget class="QProgressBar" name="connectProgress">
     <property name="geometry">
      <rect>
       <x>90</x>
       <y>100</y>
       <width>261</width>
       <height>23</height>
      </rect>
     </property>
     <property name="value">
      <number>0</number>
     </property>
    </widget>
    <widget class="QLabel" name="label">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>10</y>
       <width>61</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>ip - adress</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_2">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>40</y>
       <width>61</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>username</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_3">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>70</y>
       <width>61</width>
       <height>20</height>
      </rect>
     </property>
     <property name="text">
      <string>password</string>
     </property>
    </widget>
    <widget class="QLineEdit" name="port">
     <property name="geometry">
      <rect>
       <x>270</x>
       <y>10</y>
       <width>51</width>
       <height>20</height>
      </rect>
     </property>
     <property name="inputMask">
      <string>0009</string>
     </property>
     <property name="text">
      <string>5544</string>
     </property>
    </widget>
    <widget class="QLabel" name="label_4">
     <property name="geometry">
      <rect>
       <x>240</x>
       <y>10</y>
       <width>31</width>
       <height>16</height>
      </rect>
     </property>
     <property name="text">
      <string>port:</string>
     </property>
    </widget>
    <widget class="QCheckBox" name="cryptedConnection">
     <property name="geometry">
      <rect>
       <x>240</x>
       <y>40</y>
       <width>121</width>
       <height>17</height>
      </rect>
     </property>
     <property name="text">
      <string>Cryptred connection</string>
     </property>
    </widget>
   </widget>
   <widget class="QLineEdit" name="command">
    <property name="geometry">
     <rect>
      <x>720</x>
      <y>560</y>
      <width>401</width>
      <height>21</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>Command</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="command_log">
    <property name="geometry">
     <rect>
      <x>720</x>
      <y>130</y>
      <width>401</width>
      <height>431</height>
     </rect>
    </property>
   </widget>
   <widget class="QTreeWidget" name="files_tree">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>721</width>
      <height>581</height>
     </rect>
    </property>
    <column>
     <property name="text">
      <string notr="true">1</string>
     </property>
    </column>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1121</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFilecloud">
    <property name="title">
     <string>Files</string>
    </property>
    <addaction name="actionCreate_connection_file"/>
    <addaction name="actionOpen_connection_file"/>
    <addaction name="separator"/>
    <addaction name="actionDocx"/>
    <addaction name="separator"/>
   </widget>
   <widget class="QMenu" name="menuFilecloud_2">
    <property name="title">
     <string>Filecloud</string>
    </property>
    <addaction name="actionAbout"/>
    <addaction name="actionCreator"/>
    <addaction name="separator"/>
    <addaction name="actionSettings"/>
   </widget>
   <widget class="QMenu" name="menuTools">
    <property name="title">
     <string>Tools</string>
    </property>
    <addaction name="actionDebug_mode"/>
    <addaction name="actionServer_propertes"/>
   </widget>
   <widget class="QMenu" name="menuServer">
    <property name="title">
     <string>Server</string>
    </property>
    <addaction name="actionDisconnect"/>
    <addaction name="actionChech_connection"/>
    <addaction name="actionInstall_plugin"/>
    <addaction name="separator"/>
    <addaction name="actionMore_commands"/>
   </widget>
   <addaction name="menuFilecloud"/>
   <addaction name="menuFilecloud_2"/>
   <addaction name="menuTools"/>
   <addaction name="menuServer"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionCreate_connection_file">
   <property name="text">
    <string>Create connection file</string>
   </property>
  </action>
  <action name="actionOpen_connection_file">
   <property name="text">
    <string>Open connection file</string>
   </property>
  </action>
  <action name="actionDocx">
   <property name="text">
    <string>Docx</string>
   </property>
  </action>
  <action name="actionAbout">
   <property name="text">
    <string>About</string>
   </property>
  </action>
  <action name="actionCreator">
   <property name="text">
    <string>Creator</string>
   </property>
  </action>
  <action name="actionSettings">
   <property name="text">
    <string>Settings</string>
   </property>
  </action>
  <action name="actionDebug_mode">
   <property name="checkable">
    <bool>true</bool>
   </property>
   <property name="checked">
    <bool>false</bool>
   </property>
   <property name="text">
    <string>Debug mode</string>
   </property>
  </action>
  <action name="actionServer_propertes">
   <property name="text">
    <string>Server properties</string>
   </property>
  </action>
  <action name="actionDisconnect">
   <property name="text">
    <string>Disconnect</string>
   </property>
  </action>
  <action name="actionChech_connection">
   <property name="text">
    <string>Check connection</string>
   </property>
  </action>
  <action name="actionInstall_plugin">
   <property name="text">
    <string>Install plugin</string>
   </property>
  </action>
  <action name="actionMore_commands">
   <property name="text">
    <string>More commands...</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections/>
</ui>

Сервер:

import socketserver
from loguru import logger
from cryptography.fernet import Fernet
from pathlib import Path
import os


def build_tree(path):
    tree = []
    for element in os.listdir(path):
        if os.path.isfile(f"{path}/{element}"):
            tree.append((element))
        elif os.path.isdir(f"{path}/{element}"):
            tree.append({element: build_tree(f"{path}/{element}")})

    return tree


tr = str(build_tree("./files"))
print(tr)
exec(f"some = {tr}")
print(some)

settings = {
    "AUTHORIZE_REQUIRE": True,
    "USERS": {"ivan": "password"},
}


class Connector(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                print(accepted)
                self.data = self.request.recv(1024).strip()
                logger.info(f"Received from {self.client_address[0]}:")
                logger.info(self.data)

                self.data_compiled = self.data.decode("utf-8").split()
                print(self.data_compiled)

                if self.data_compiled[0] == "HELLO":
                    for i in self.data_compiled:
                        print(i)
                        if "login=" in i:
                            self.login = i.split("=")[-1]
                        if "password=" in i:
                            self.password = i.split("=")[-1]
                    if self.login in settings["USERS"].keys() and self.password in settings["USERS"].values():
                        accepted.append(self.client_address[0])
                        if len(self.data_compiled) > 1:
                            if self.data_compiled[1] == "crypted_connection":
                                key = Fernet.generate_key()
                                crypted_connections[self.client_address[0]] = key.decode("utf-8")
                                self.request.sendall(bytes("HELLO client\nYour key: {}".format(crypted_connections[self.client_address[0]]), "utf-8"))
                            else:
                                self.request.sendall(b"HELLO client")
                        else:
                            self.request.sendall(b"HELLO client")
                    else:
                        self.request.sendall(
                            bytes("Executing error: permission denided", "utf-8"))


                elif self.client_address[0] in accepted:
                    if self.data_compiled[0] == "FILES":
                        if len(self.data_compiled) > 1:
                            if self.data_compiled[1] == "GET":
                                tr = str(build_tree("./files"))

                                self.request.sendall(bytes(tr, "utf-8"))

                            elif self.data_compiled[1] == "POST":
                                self.request.sendall(bytes("Post", "utf-8"))

                            else:
                                self.request.sendall(bytes("Error", "utf-8"))

                    elif self.data_compiled[0] == "INFOR":
                        info = {
                            "IS_CRYPTED": self.client_address[0] in crypted_connections.keys(),
                            "CLIENT_INFO": self.client_address,
                            "SERVER_INFO": self.server,
                            "UPTIME": None
                        }
                        self.request.sendall(bytes(str(info), "utf-8"))

                    else:
                        self.request.sendall(b"Command compiling error: unknown command")
                else:
                    self.request.sendall(b"Executing error: permission denided")
            except Exception as e:
                print(e)


if __name__ == "__main__":
    with socketserver.ThreadingTCPServer(("0.0.0.0", 5544), Connector) as server:
        accepted = []
        crypted_connections = {}
        server.serve_forever()

Ответы (0 шт):