Search code examples
python-3.xsocketstkinterwindow

Window tkinter doesn't display when there is a connection with another device


  • I would like to connect 2 computers in order to make a kind of messenger, but I would like to use tkinter, in order to have windows, and use buttons and other widgets to create the interface.
  • So I have 2 programs, one is the client, and the other is the server.
    • For the client, it works : the window displays, and I can send message.
    • For the server, the window doesn't display.

client program:

import socket
from tkinter import *

def envoyer_msg():
    s.send(msg.get().encode())

fenetre=Tk()
fenetre.geometry("{}x{}+{}+{}".format(200,200,200,200))

texte=Label(fenetre,text="CLIENT",font=25)
texte.pack()

msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()

bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()

s = socket.socket()
s.connect(('127.0.0.1',12345))

and here the server program :

import socket
from tkinter import *

def envoyer_msg():
    c.send(msg.encode())

fenetre=Tk()
fenetre.geometry("{}x{}+{}+{}".format(200,200,200,200))

texte=Label(fenetre,text="SERVEUR",font=25)
texte.pack()

msg=StringVar()
saisie=Entry(fenetre,textvariable=msg,font=25)
saisie.pack()

bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
bouton_envoyer.pack()

print("1")

s = socket.socket()
port = 12345
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print ("Socket Up and running with a connection from",addr)

print("2")

while True:
    rcvdData = c.recv(1024).decode()
    print ("S:",rcvdData)

    print("3")

Solution

  • First you should call mainloop() explicitly even though you are using an IDE made with tkinter like Python IDLE. Otherwise the GUI won't show up when the script is executed in a terminal.


    The server GUI does not show up because the while loop blocks the mainloop(). You need to put the client connection handling task in a thread:

    # server code
    import socket
    import threading
    from tkinter import *
    
    def envoyer_msg():
        c.send(msg.get().encode())
    
    fenetre=Tk()
    fenetre.geometry("{}x{}+{}+{}".format(200,200,200,200))
    
    texte=Label(fenetre,text="SERVEUR",font=25)
    texte.pack()
    
    msg=StringVar()
    saisie=Entry(fenetre,textvariable=msg,font=25)
    saisie.pack()
    
    bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
    bouton_envoyer.pack()
    
    def server_task():
        global c
    
        s = socket.socket()
        port = 12345
        s.bind(('', port))
        s.listen(5)
    
        while True:
            print('waiting connection ...')
            c, addr = s.accept()
            print ("Socket Up and running with a connection from", addr)
    
            while True:
                try:
                    rcvdData = c.recv(1024).decode()
                    print ("Client:", rcvdData)
                except ConnectionResetError:
                    print('Client disconnected')
                    break
    
    # start the client connection handling thread
    threading.Thread(target=server_task, daemon=True).start()
    fenetre.mainloop()
    
    

    Same applies on the client side:

    # client code
    import socket
    import threading
    from tkinter import *
    
    def envoyer_msg():
        s.send(msg.get().encode())
    
    fenetre=Tk()
    fenetre.geometry("{}x{}+{}+{}".format(200,200,400,200))
    
    texte=Label(fenetre,text="CLIENT",font=25)
    texte.pack()
    
    msg=StringVar()
    saisie=Entry(fenetre,textvariable=msg,font=25)
    saisie.pack()
    
    bouton_envoyer=Button(fenetre,text="Envoyer",font=25,command=envoyer_msg)
    bouton_envoyer.pack()
    
    def client_task():
        global s
        s = socket.socket()
        s.connect(('127.0.0.1',12345))
        while True:
            try:
                rcvdData = s.recv(1024).decode()
                print('Server:', rcvdData)
            except ConnectionResetError:
                print('Server disconnected')
                fenetre.destroy()
    
    # start the server connection thread
    threading.Thread(target=client_task, daemon=True).start()
    fenetre.mainloop()
    

    Since you want to use GUI, better use a Text widget to hold the peer messages instead of using print().