Home > Blockchain >  Using Ping constantly to verify connection and display feedback on python tkinter
Using Ping constantly to verify connection and display feedback on python tkinter

Time:02-24

I am trying to make a small app with python tkinter. in which i will need a ping command to constantly check for connection to a certain device example '192.168.1.21' and tells me if the device is connected or not real time. Nota: i am using ping3 this is my program:

root = Tk()
root.geometry("400x400")
label_1 = Label(root, text = "Not connected")
label_1.pack()




def testing(label):
    if ping('192.168.1.21', timeout=0.5) != None: #To test the connection 1 time
        label.config(text = "Connected")
    else:
        label.config(text = "Not Connected")

    label.after(500, lambda : testing(label_1))

def popup(): #A popup that does the same thing
    top = Toplevel(root)
    top.geometry("150x150")
    label_2 = Label(top, text = "Not connected")
    label_2.pack()
    label_2.after(500, lambda : testing(label_2))
    top.mainloop()

btn = Button(root, text = "Popup", command=popup)
btn.pack()

testing(label_1)

root.mainloop()

How can i make it not freeze and keep testing while letting the rest of the program run smoothly. Thank you and sorry if I made mistakes in the code, i am still new to python in generale.

CodePudding user response:

You can achieve this using threading. This allows the tkinter mainloop and the pinging to happen concurrently which means the GUI doesn't freeze.

import threading, time, sys

root = Tk()
root.geometry("400x400")
label_1 = Label(root, text = "Not connected")
label_1.pack()


current_value = None
continue_thread = True

def doPing():
    global current_value, continue_thread
    while continue_thread:
        current_value = ping('192.168.1.21', timeout=0.5)
        time.sleep(0.5) # 500ms delay before pinging again
    sys.exit() # Stop thread when window is closed


def testing(label):
    global current_value
    if current_value != None: #To test the connection 1 time
        label.config(text = "Connected")
    else:
        label.config(text = "Not Connected")

    label.after(500, lambda : testing(label))

def popup(): #A popup that does the same thing
    top = Toplevel(root)
    top.geometry("150x150")
    label_2 = Label(top, text = "Not connected")
    label_2.pack()
    label_2.after(500, lambda : testing(label_2))
    top.mainloop()

btn = Button(root, text = "Popup", command=popup)
btn.pack()

ping_thread = threading.Thread(target = doPing)
ping_thread.start()
testing(label_1)

root.mainloop()
continue_thread = False # end thread after window is closed

The program now uses a thread, ping_thread, which runs doPing. doPing calls ping, updates current_value and then waits 500ms before calling itself again. Then in the main thread testing updates the label every 500ms using the value of current_value. When the window is closed and root.mainloop has finished continue_thread is set to false so then sys.exit is called, stopping the thread.

There are 2 global variables current_value and continue_thread. The first allows you to access the return value of ping in testing and the second allows the main thread to tell the ping thread to stop when the Tkinter window is closed. Global variables are not good programming practice and I'd advise using classes instead. I've used them here for the sake of simplicity.

  • Related