Home > OS >  Printing server output data in tkinter Text widget
Printing server output data in tkinter Text widget

Time:04-06

I have a Text widget in tkinter and I want to capture and put a server output in it.

Project folder:

project
| main.py
| servers_folder
| | default_server.py

In my main. I'm importing default_Server.py, it has to be another file because I have a function that creates another server with some changeable settings so when I want to run the server I press a button and enter a server (file) name and import it with server = importlib.import_module(server_name)

main.py server run function sample:

def connect(server_name):
    for widget in frame.winfo_children():
        widget.grid_forget()

    def run():
        server = importlib.import_module(server_name)
        server.Server().start()

    command = Text(frame)
    command.grid(row=0, column=0)

    thread = t.Thread(target=run)
    thread.start()


Label(frame, text='Server name:').grid(row=0, column=0)
server_name = Entry(frame)
server_name.grid(row=0, column=1, sticky='NSEW')
Button(frame, text='Run server', command=lambda: connect(server_name.get())).grid(row=1, column=0, columnspan=2)

Server start function:

def start(self):
    print('[STARTING] Server is starting...')
    self.server.listen()
    print(f'[LISTENING] Server is listening on {self.SERVER}')
    while True:
        conn, addr = self.server.accept()
        thread = t.Thread(target=self.handle_client, args=(conn, addr))
        thread.start()

Server handle_client function:

def handle_client(self, conn, addr):
    print(f'[NEW CONNECTION] {addr} connected.')
    print(f'[ACTIVE CONNECTIONS] {t.active_count() - 1}')

    connected = True
    while connected:
        msg_lenght = conn.recv(self.HEADER).decode(self.FORMAT)
        if msg_lenght:
            msg_lenght = int(msg_lenght)
            msg = conn.recv(msg_lenght).decode(self.FORMAT)
            if msg == self.DISCONNECT_MESSAGE:
                connected = False

            print(f'[MESSAGE RECIEVED] FROM: {addr}; Message: {msg}')
            conn.send('Message received!'.encode(self.FORMAT))

    conn.close()

How can I capture this prints and put them in my tkinter Text widget in my main.py run function? It doesn't have to be capturing prints, I just need a way to display it on my Text widget when starting the server and when it's running to display through a while loop everything that is going on afterwards. Also it needs to be imported because of the ability to create new servers and run them by their names that are stored as file names of servers.

Thanks for help!

CodePudding user response:

It would be easily for me to see the full code, but I think you can do something similar to this:

def start(self, msg_callback):
    print('[STARTING] Server is starting...')
    self.msg_callback = msg_callback
    self.server.listen()
    print(f'[LISTENING] Server is listening on {self.SERVER}')
    while True:
        conn, addr = self.server.accept()
        thread = t.Thread(target=self.handle_client, args=(conn, addr))
        thread.start()


def handle_client(self, conn, addr):
    print(f'[NEW CONNECTION] {addr} connected.')
    print(f'[ACTIVE CONNECTIONS] {t.active_count() - 1}')

    connected = True
    while connected:
        msg_lenght = conn.recv(self.HEADER).decode(self.FORMAT)
        if msg_lenght:
            msg_lenght = int(msg_lenght)
            msg = conn.recv(msg_lenght).decode(self.FORMAT)
            self.msg_callback(msg)
            if msg == self.DISCONNECT_MESSAGE:
                connected = False

            print(f'[MESSAGE RECIEVED] FROM: {addr}; Message: {msg}')
            conn.send('Message received!'.encode(self.FORMAT))

    conn.close()


def connect(server_name):
    for widget in frame.winfo_children():
        widget.grid_forget()

    command = Text(frame)
    command.grid(row=0, column=0)
    
    def msg_callback(msg):
        command.delete('1.0', END)
        command.insert('1.0', msg)

    def run():
        server = importlib.import_module(server_name)
        server.Server().start(msg_callback)

    thread = t.Thread(target=run)
    thread.start()


Label(frame, text='Server name:').grid(row=0, column=0)
server_name = Entry(frame)
server_name.grid(row=0, column=1, sticky='NSEW')
Button(frame, text='Run server', command=lambda: connect(server_name.get())).grid(row=1, column=0, columnspan=2)
  • Related