Client-Server comm. in PyQt5

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Finux: Also für mich sieht das alles noch sehr weit von Ziel entfernt aus. Da fehlt was grundlegendes — vielleicht wurde das noch nicht erwähnt, aber TCP ist ein Datenstrom, da braucht man ein Protokoll um die einzelnen Nachrichten auseinander halten zu können und feststellen zu können wann eine Nachricht komplett ist. Zur Semantik von `recv()` könnte man auch was sagen. ``recv(4096).decode("utf-8")`` wäre auch kaputt wenn der darauf folgende Code tatsächlich mit mehr oder weniger beliebigen Teilausschnitten des Datenstroms klar kommen würde, denn dekodieren als UTF-8 tut das schon nicht.

Der Client/Server-Code funktioniert schon nicht, und Du tackerst da jetzt mit GUI-Programmierung eine weitere Komplexitätsstufe drauf.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Sirius3
User
Beiträge: 18253
Registriert: Sonntag 21. Oktober 2012, 17:20

@Finux: Sternchenimporte sind auch bei Qt schlecht. `sys.exit` sollte insbesondere bei Threads nicht benutzt werden. Was sollen denn diese u_-Präfixe bei den Variablen?
`login` sendet jetzt wirklich ohne Trennung mehrere Daten, die so niemals über eine Internetleitung als Einzelpakete ankommen dürften.
Bitte behaupte nirgends, Du hättest mit dem Hashing irgendwelche Passwörter geschützt.
Was soll diese while-True Schleife in `login`? Sowas in einer Funktion zu finden, die Login heißt, ist nur verwirrend.
Ein so kleiner sleep-Wert ist unsinnig. Die Klammern um die Bedingungen sind überflüssig. Dass `msg_changed`-Signale Freitextfelder sind, reiht sich gut in die lange Liste von DON'Ts.
In `Window.__init__` gehört kein `show`. Widgets sorgen nicht dafür, dass sie dargestellt werden, das macht die Instanz darüber.
`Window.UI` ist eine Methode, die sofort in __init__ wandern sollte und der Unterschied zwischen mainDesign und layout ist auch nicht vorhanden, so dass beides auch direkt in __init__ stehen sollte. Da auf die Layouts nie wieder zugegriffen werden muß, sollten das keine Attribute sein.
Und benutze keine Abkzng. Heißt es nun msg oder messg oder mig? Nein, es heißt einfach immer messsage.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du machst einen Fehler indem du die Text-Felder an Communication uebergibst. Denn dann greifst du darauf aus einem anderen Thread auf GUI-Element zu, und ob das geht, oder mit einem harten Absturz endet ist reine Glueckssache. Gib stattdessen gleich die Werte fuer Namen und Passwort ein. Threads sind schwer. Du denkst QSocketNotifier waere es, aber das stimmt nicht. Threads sehen einfach aus, doch die Teufel im Detail sind derer viele, und gemein. Weil sie sich nicht immer, aber manchmal zeigen.

Wenn du ausserdem den socket ausserhalb von communication erzeugst (zb in einer Funktion), und den dann sowohl an Communication im Konstruktor uebergibst, als ihn dir auch in deiner GUI zu speichern, dann kannst du auch spaeter etwas senden. Communication muss in diesem Fall einfach nur am Ende von login in einer endlosschleife auf Daten vom Socket warten, und die mit einem Signal weiterreichen.

Das du mit nur einem Signal arbeitest, um Daten und als Texte gehaltene Fehlermeldungen zu verschicken ist auch nicht gut. Mach ein Signal daraus, das die rohen socket-Daten verschickt, und ein zweites, das den Zustand der Verbindung kommuniziert. ZB als Enum. Und in der GUI reagierst du dann auf diese Zustandsaenderungen, zB durch enablen/disablen von widgets etc.

Und du musst DRINGEN login_btn umbenennen. Der Name war schon immer schlecht, aber jetzt passt er ueberhaupt nicht mehr. Das passiert ja immer, und sollte das auch. Nenn das zB start_communication_thread oder etwas aehnliches. Es ist auch hochgradig verwirrend, dass du darin den auth_checker anlegst, auf den du dich dann mit " self.btn_login.clicked.connect(self.auth_checker.login)" beziehst. Mach das gleich IN der Methode, denn dann sieht man, dass das zusammengehoert.
Antworten