0

for a project I need to create a Tkinter GUI which displays the data sent by Socket. I thought about the after() method but I don't know how to use it. Can someone helps me ? Thanks

Here's my whole code: https://pastecode.xyz/view/5b23d322

and here's only the function that check if there's something arriving:

def verifsock():
   global socket
   socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   socket.bind(('172.16.2.220', 15555))

   socket.listen(5)
   client, address = socket.accept()
   print ("{} connected".format( address ))

   response = client.recv(255)
   if response != "":
       log.insert(END, response)
   else:
       return

EDIT:

def eleve2():


quitterMDPeleve()
global eleve2
eleve2 = tk.Tk()
eleve2.title("Espace élèves")
eleve2.config(bg='#A26F65')
eleve2.geometry('1650x1050')

global logRec

logRec = tk.Text(eleve2, width=25, height=20, takefocus=0, font = ('Tw Cen MT', 15))
logRec.place(x=400, y=310, anchor='w')

global threadEl

threadEl = threading.Thread(target=verifsock)
threadEl.daemon = True # without the daemon parameter, the function in parallel will continue even your main program ends
threadEl.start()

eleve2.mainloop()

and the function called:

def verifsock():
global socket
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(('172.16.2.220', 15555))

socket.listen(5)
client, address = socket.accept()
print ("{} connected".format( address ))

response = client.recv(255)
if response != "":
    logRec.insert(END, response)
else:
    return
Armczbt
  • 21
  • 7
  • You may need to use a separate `Thread` for this because `socket.accept()` will block until a client connects. You can push the data from the `client.recv()` into a queue and use `after` to repeatedly check this queue. – quamrana Mar 04 '20 at 16:08
  • Does this answer your question? [Running a thread with Tkinter object](https://stackoverflow.com/questions/56117419/running-a-thread-with-tkinter-object) – quamrana Mar 04 '20 at 16:13

2 Answers2

0

Few tips :

You will need to do multiple "infinite loops" (like while True) using threads :

  • one loop to accept new connections
  • one loop waiting for messages (the receiver)
  • one loop for the graphic interface (your tkinter.Tk().mainloop())

You do not need the after() event. For example you can, when receiving a socket message, update a variable in GUI.

EDIT

Here is a little example using threads. The main program just create a thread, waits 3 seconds, and prints "end main program". The parallel thread executes the function counter() that prints an incrementing variable each second.

import threading
import time

def counter():
    c = 0
    while True:
        print(c)
        c += 1
        time.sleep(1)

thread_1 = threading.Thread(target=counter)
thread_1.daemon = True # without the daemon parameter, the function in parallel will continue even your main program ends
thread_1.start()

# MAIN PROGRAM
time.sleep(3)
print("end main program")
Phoenixo
  • 2,071
  • 1
  • 6
  • 13
  • 1
    btw all programs have one thread already and its usual for `tkinter` to run in that thread. You can start another thread which blocks on `accept()` and spawns a new `Thread` for each connection. – quamrana Mar 04 '20 at 16:10
  • Also updating the GUI from another thread usually doesn't work. – quamrana Mar 04 '20 at 16:11
  • I completely agree, I never said he had to create a thread for `tkinter`. I said he would need multiple `loops`, which can be achieved using `threads` – Phoenixo Mar 04 '20 at 17:11
  • @Armczbt : see my EDIT answer with a little example using `threads` – Phoenixo Mar 04 '20 at 17:27
  • Thanks, this really helped me. However I have a new problem.. Once I send a first thing by socket, I can't send anything after... (SEE MY EDIT) – Armczbt Mar 05 '20 at 08:12
0

I finally managed to solve this problem, thanks to everyone who helped me ;)

Here's my code for those who are interested :

def eleve2():


quitterMDPeleve()
global eleve2
eleve2 = tk.Tk()
eleve2.title("Espace élèves")
eleve2.config(bg='#A26F65')
eleve2.geometry('1650x1050')

global logRec

logRec = tk.Text(eleve2, width=25, height=20, takefocus=0, font = ('Tw Cen MT', 15))
logRec.place(x=400, y=310, anchor='w')

global threadEl

threadEl = threading.Thread(target=verifsock)
threadEl.daemon = True # without the daemon parameter, the function in parallel will continue even your main program ends
threadEl.start()

eleve2.mainloop()



def verifsock():
global socket
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(('172.16.2.220', 15555))
while True:

    socket.listen(5)
    client, address = socket.accept()
    print ("{} connected".format( address ))

    response = client.recv(255)
    response2 = response.decode("utf-8")
    if response2 != "":
        logRec.insert(END, str(response2)+"\n")
    else:
        return
Armczbt
  • 21
  • 7