ich möchte gerne meine clientseitige Logik in eine PyQt5 GUI implementieren. Stoße da aber auf mir nicht so ganz erklärbare Probleme.
Vorab noch eins: Die Kommunikation der client-Logik ist nicht stabil, und auch generell sind einige Sachen äußerst mangelhaft. Mir geht es hier in erster Linie aber um die logische Verknüpfung zu der GUI. OOP-Kenntnisse sind bei mir kaum vorhanden.
Mein Ziel ist es alle Serverantworten in (am liebsten wie in einer Konsolenansicht) in "middleLayout" (output = QLabel --> output.setText) der GUI auszugeben. Ich vermute, dass ich den Code ganz anders strukturieren muss, finde aber keinen vernünftigen Ansatz dafür...
Zudem kommt noch, dass die Kommunikation wenigstens mit dem "msg_send"child-Thread dauerhaft offen bleiben soll (wie kann ich mein command-textfeld via Entertasten-event in mein "send-msg-thread" transportieren? theoretisch würde mir der main-thread für einzelne sendings ja ausreichen und ich kann die Killer-while-Schleife rausschmeißen..)
Vielleicht könnt ihr helfen:
Code: Alles auswählen
import socket, ssl, pprint, sys
import threading
import time
import hashlib
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPixmap, QFont
IP = '127.0.0.1'
PORT = 4600
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("CSK Control - YOU NEED TO LOGIN!")
        self.setGeometry(200, 200, 1500, 700)
        self.UI()
        self.show()
       
    def UI(self):
        self.mainDesign()
        self.layout()
    def mainDesign(self):
        ######### left layout widgets #########
        self.u_name_label = QLabel("Username: ")
        self.u_name_input = QLineEdit(self)
        self.u_name_input.setPlaceholderText("auth. user: hell pw:1234")
        self.u_pwd_label = QLabel("Password: ")
        self.u_pwd_input = QLineEdit(self)
        self.u_pwd_input.setEchoMode(QLineEdit.Password)
        self.u_pwd_input.setPlaceholderText("Enter Password")
        self.btn_login = QPushButton("LOGIN", self)
        self.btn_login.clicked.connect(self.connect_to_server)
        ######### middle layout widgets #########
        self.output = QLabel(self)
        self.output.setStyleSheet("background-color: white; font-size: 20pt")
        self.output.setText("TEST")
            ######### middle layout bottom widgets #########
        self.command_label = QLabel(self)
        self.command_label.setText("Command: ")
        self.command_input = QLineEdit(self)
        self.command_input.setPlaceholderText("Enter server command here")
        ######### right layout widgets #########
        self.status = QLabel("STATUS")
        self.status.setStyleSheet("background-color: red; font-size: 16pt")
        #self.u_name_label.setStyleSheet('font-family:Arial Bold')
    def layout(self):
        ######### creating main layout #########
        self.mainLayout = QHBoxLayout()
        self.leftLayout = QFormLayout()
        self.middleLayout = QVBoxLayout()
        self.middleLayout_bottom = QHBoxLayout()
        self.rightLayout = QVBoxLayout()
        ######### adding child layouts #########
        self.mainLayout.addLayout(self.leftLayout, 10)
        self.mainLayout.addLayout(self.middleLayout, 70)
        self.middleLayout.addLayout(self.middleLayout_bottom)
        self.mainLayout.addLayout(self.rightLayout, 20)
        ######### adding widgets #########
            ######### left layout #########
        self.leftLayout.addWidget(self.u_name_label)
        self.leftLayout.addWidget(self.u_name_input)
        self.leftLayout.addWidget(self.u_pwd_label)
        self.leftLayout.addWidget(self.u_pwd_input)
        self.leftLayout.addWidget(self.btn_login)
            ######### middle layout #########
        self.middleLayout.addWidget(self.output)
        self.middleLayout_bottom.addWidget(self.command_label)
        self.middleLayout_bottom.addWidget(self.command_input)
            ######### right layout #########
        self.rightLayout.addWidget(self.status)
        self.rightLayout.addStretch()
        ######### selecting main layout for window #########
        self.setLayout(self.mainLayout)
    def connect_to_server(self):
        context = ssl.SSLContext()
        context.verify_mode = ssl.CERT_REQUIRED
        context.check_hostname = True
        try:
            context.load_verify_locations("/home/fin/server.crt")
            print("***CHECK 1/4- Certificate loading successful")
        except (FileExistsError, FileNotFoundError) as e:
            print(e)
            print("::::: Program will be closed now! :::::")
            sys.exit()
        try:
            # with socket.create_connection((ip, port)) as s:
            conn = context.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), server_hostname="127.0.0.1")
            print("***CHECK 2/4- Socket only supports ssl connection successful")
            try:
                conn.connect((IP, PORT))
                print("***CHECK 3/4- Connection to server successful")
                conn.sendall(b"Thanks for accepting the connection!")
                print("***CHECK 4/4- Bytestring sending successful")
            except:
                print("CONNECTION NOT POSSIBLE! IN 10 SECONDS TRYING TO CONNECT AGAIN..")
                time.sleep(10.0)
                return
        except ssl.CertificateError as e:
            # print("Error {}: {}".format(e.args[0], e.args[1]))
            # print("Error {}:".format(e))  #TODO: Darf Ziel-IP bekannt sein? (Fehlerprovokation bei Hackern) SICHERHEITSMANGEL!
            print("Hostname doesn't match.")
            print("::::: Program will be closed now! :::::")
            sys.exit()
        except ConnectionError as e:
            print(e)
            print("::::: Program will be closed now! :::::")
            sys.exit()
        tell_auth = "username"
        u_name_input = self.u_name_input.text()
        u_pwd_input = self.u_pwd_input.text()
        u_pwd_input = hashlib.sha512(bytes(u_pwd_input, "utf-8"))
        pwd_message = (u_pwd_input.hexdigest())
        conn.sendall(tell_auth.encode("utf-8"))
        conn.sendall(u_name_input.encode("utf-8"))
        conn.sendall(pwd_message.encode("utf-8"))
        msg = conn.recv(4096).decode("utf-8")
        print("\n[{}]: {}".format(IP, msg))
        # self.output.setText("TEST")
        if msg == "Authentication succeeded!":
            # TODO: was passiert nach der succeed message?
            self.setWindowTitle("CSK Control - User: " + self.u_name_input.text())
            self.output.setText(msg)
            t1 = threading.Thread(target=self.msg_receive, args=(conn, IP))
            t1.start()
            t2 = threading.Thread(target=self.msg_print_send, args=(conn, IP))
            t2.start()
            # z = t1.isAlive()
            # print(z)
            # g = t2.isAlive()
            # print(g)
            # c = threading.active_count()
            # print("how many threads are alive: ", c)
            try:
                while 1:
                    # pass
                    time.sleep(1)
            except KeyboardInterrupt as e:
                print(e)
        elif msg == "Authentication failed!":
            self.setWindowTitle("LOGIN FAILED!" + self.u_name_input.text())
    def msg_receive(self, conn, IP):
        try:
            while True:
                i = threading.get_ident()
                print("RECEIVE: ", i)
                msg = conn.recv(4096).decode("utf-8")
                print("\n[{}]: {}".format(IP, msg))
                time.sleep(0.000001)
                if msg == '':
                    print("LOST CONNECTION TO SERVER!")
                    print("TRYING TO RECONNECT... (Refresh Browser!)")  # TODO:
                    conn.close()
                    break
        except OSError as e:
            return
    def msg_print_send(self, conn, IP):
        while True:
            y = threading.get_ident()
            print("SENDING: ", y)
            message = input("\nNachricht: ")
            conn.sendall(message.encode("utf-8"))
            if message == 'exit':
                print("+++++ SOCKET CLOSED +++++")
                conn.close()
                sys.exit()  # TODO: skript beendet sich nicht
                break
def main():
    # -----------------GUI-----------------#
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec_())
    # -------------------------------------#
if __name__ == '__main__':
    main()
Achso, der aktuelle Stand in meinem Code ist, dass ich die Logindaten von der GUI zum Server schicken kann, die Antwort-accepted-Nachricht erkenne ich auch, aber dann hängt sich die GUI auf...
LG,
Finux
