Search code examples
pythonsocketstkinterprocessmainloop

how to make a code that does 2 processes in python


i made a messenger that works with the socket library. it has 2 sides : server and client. i later decided to make a GUI for it , too. ( with tkinter ) when i was making it , i realized that programs does not work correctly. here :

import socket
from tkinter import *
win = Tk()
win.geometry("300x300")
win.resizable(False,False)


def disc() :
    s = socket.socket()
    ip = "0.0.0.0"
    port = 9999
    s.bind((ip,port))
    s.listen()
    print ('please wait...')
    c , addr =s.accept()
    print ('someone has joined!')


    while True :
        msg = input('your message : ' )
        c.send(msg.encode('utf8'))
        print (c.recv(1024).decode())

lbl_1 = Label(win,text="mychat",bg="light blue")
lbl_1.place(x=130,y=20)

lbl_2 = Label(win,text="your message: ")
lbl_2.place(x=130,y=50)


lbl_3 = Label(win,text="recieved message: ")
lbl_3.place(x=130,y=70)

btn_1 = Button(win,text="make your device discoverable",command=disc)
btn_1.pack()

txt_1 = Text(win)
txt_1.pack()

word = "messages"
txt_1.insert(END, word)

win.mainloop()

here , you can see what i've tried. i have two parts : the socket part and the gui part. the socket part is in the def block. but this does not work correctly. if you put the mainloop before socket part , it will never be executed because mainloop is not finished until i close the program.

if you put main loop after socket part , the GUI will not be displayed until someone join the server.(because socket part is not finished)

here , you see i've tried another thing. i put the socket part in def and then made a button for it. but this doesn't work either. when you press the button , the program stops and gives a ( not responding ) error on title bar . ( so until someone has joined , it will not respond. )

i want a solution for this code that the GUI part works and doesn't care to socket part(dismissing it). in other words , python executes the 2 parts in one time.


Solution

  • Sounds like you want to start using threads.

    You basically have two "while True" loops, the first is the win.mainloop() that stops executing when the user exists the GUI. The second is the while True in the disc function, that waits for input from the user (msg = input(...)) and then waits for data from the client (s.recv)

    import threading
    
    def disc():
        ...
    
    connection = threading.Thread(target=disc).start()
    

    The rest of the GUI code goes below the connection thread without the make your device discoverable part as it is now unnecessary:

    # remove this part
    btn_1 = Button(win,text="make your device discoverable",command=disc)
    btn_1.pack()