Вылетает приложение 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()