0

I've tried everything but I don't understand at all how to apply threads. Please, someone kind could give me an indication of how to do it right? I have tried several examples and the result is always the same. The "stop" button does not stop until the "ping" loop has finished. Please, I'm a newbie, give me a simple explanation of how to apply the thread

from tkinter import *
from tkinter import ttk
from tkinter import scrolledtext
import pandas as pd
from pythonping import ping
from datetime import datetime
import numpy as np

running = False  # Global flag

def start_ping():
    
    if running:  # Only do this if the Stop button has not been clicked
        
        indices_tabla = tabla.get_children()
        
        for x_fila in range(0,df_registro.shape[0]):
            
            celda_nombres =  list(df_registro["NOMBRE"])[x_fila]
            celda_ip = list(df_registro["IP"])[x_fila]

            ping_equipo = ping(str(celda_ip), count=1)
                           
            msg = (celda_nombres + ' (' + celda_ip + ')\n' +
                   '\n' +
                   str(datetime.now()) + '\n' +
                   '\n' +
                   str(ping_equipo) + '\n' +
                   '\n' +
                   '--------------------------------------------------' + '\n' + '\n')
            
            text_box.insert(END, msg)

            text_box.yview(END)
            text_box.update()
            
            if ping_equipo.success():
                
                
                df_registro.at[x_fila,'P. Enviados'] = int(df_registro.at[x_fila,'P. Enviados']) + 1
                
                celda_p_enviados = df_registro.at[x_fila,'P. Enviados']
                celda_p_perdidos = df_registro.at[x_fila,'P. Perdidos']
                
                tabla.delete(indices_tabla[x_fila])
                
                tabla.insert("", index=x_fila, text=str(celda_nombres), iid=str(indices_tabla[x_fila]),
                                 values=(str(celda_ip),celda_p_enviados, celda_p_perdidos, 'ONLINE'))
                
            if not ping_equipo.success():

                
                df_registro.at[x_fila,'P. Enviados'] = int(df_registro.at[x_fila,'P. Enviados']) + 1
                df_registro.at[x_fila,'P. Perdidos'] = int(df_registro.at[x_fila,'P. Perdidos']) + 1
                
                celda_p_enviados = df_registro.at[x_fila,'P. Enviados']
                celda_p_perdidos = df_registro.at[x_fila,'P. Perdidos']
                
                tabla.delete(indices_tabla[x_fila])
                
                tabla.insert("", index=x_fila, text=str(celda_nombres), iid=str(indices_tabla[x_fila]),
                                             values=(str(celda_ip),celda_p_enviados, celda_p_perdidos, 'OFFLINE'))
            
            tabla.update()
            
            if running == False:
                break
        

    # After 1 second(1sec=1000), call scanning again (create a recursive loop)
    root.after(0, start_ping)

def start():
    """Enable scanning by setting the global flag to True."""
    global running

    running = True

    text_box.insert(END, 'START \n' + '\n'
    '--------------------------------------------------' + '\n' + '\n')
    start_ping()

def stop():
    """Stop scanning by setting the global flag to False."""
    global running
    running = False
    text_box.insert(END, 'STOP \n' + '\n'
                    '--------------------------------------------------' + '\n' + '\n')
    text_box.yview(END)

def buscar_equipos():
    
    global df_registro
    
    tabla.delete(*tabla.get_children())
    
    plantilla_registro = pd.DataFrame(columns=["NOMBRE","IP","P. Enviados", "P. Perdidos", "Ultimo Estado"])

    input_lista = pd.read_excel('LISTA_PINGS.xlsx')
    
    df_registro = pd.concat([plantilla_registro,input_lista])
    
    df_registro = df_registro[:].replace(np.nan, 0)

    lista_nombres = df_registro['NOMBRE']
    
    lista_ip = df_registro['IP']
    
    lista_p_enviados = df_registro['P. Enviados']
    
    lista_p_perdidos = df_registro['P. Perdidos']

    for x_name, x_ip, x_enviados, x_perdidos in zip(lista_nombres, lista_ip, lista_p_enviados, lista_p_perdidos):
        
        tabla.insert("", END, text=x_name,
                             values=(x_ip,x_enviados,x_perdidos))
        
        tabla.update()
        

def resetar_datos():
    
    global running
    running = False

    tabla.delete(*tabla.get_children())

root = Tk()
root.title("PROGRAMA PINGS")
root.geometry("1510x600")

app = Frame(root)

app.grid()

############
# ETIQUETA #
############

lbl_pantalla_principal =  Label(app, text="PROGRAMA PINGS",
                                   font=('Helvetica', 18, "bold"))

lbl_pantalla_principal.grid(row=0 , column=0)

#################
# BUCLE VENTANA #
#################

btn_search = Button(app, text="Buscar Equipos", command = lambda: buscar_equipos())
btn_start = Button(app, text="Start Ping!", command = lambda: start())
btn_stop = Button(app, text="Stop Ping!", command = lambda: stop())
btn_reset = Button(app, text="Resetear Datos", command = lambda: resetar_datos())



btn_search.grid(row=1 , column=0)

btn_start.grid(row=2 , column=0)

btn_stop.grid(row=3 , column=0)

btn_reset.grid(row=4 , column=0)




#########
# TABLA #
#########

tabla = ttk.Treeview(app, columns=("IP","P. Enviados", "P. Perdidos", "Ultimo Estado"))

vsb = ttk.Scrollbar(app, orient="vertical", command=tabla.yview)

vsb.grid(row=5 , column=1, sticky='NS')

tabla.configure(yscrollcommand=vsb.set)

tabla.heading("#0", text="Equipo")
tabla.heading("IP", text="IP")
tabla.heading("P. Enviados", text="P. Enviados")
tabla.heading("P. Perdidos", text="P. Perdidos")
tabla.heading("Ultimo Estado", text="Ultimo Estado")


tabla.column("#0", anchor="center", width=150, stretch=NO)
tabla.column("IP", anchor="center", width=150, stretch=NO)
tabla.column("P. Enviados", anchor="center", width=150, stretch=NO)
tabla.column("P. Perdidos", anchor="center", width=150, stretch=NO)
tabla.column("Ultimo Estado", anchor="center", width=150, stretch=NO)

tabla.grid(row=5 , column=0, sticky='NS')


###################
# CUADRO DE TEXTO #
###################


text_box = scrolledtext.ScrolledText(app, undo=True)
text_box.configure(background = 'black', fg='#ffffff')
text_box['font'] = ('consolas', '12')

text_box.grid(row=5 , column=2, sticky='NS')


#################
# BUCLE VENTANA #
#################

root.mainloop()
Com Media
  • 1
  • 2
  • The loop blocks OS messages (event queue) so the window will freeze – Mike67 Nov 05 '20 at 13:42
  • You shouldn’t have loops in a GUI program. If you *must* have loops, then you could have threads, but then you can’t do any GUI updates, but you can use thread-safe queues to transfer information and instructions back to the main thread. – quamrana Nov 05 '20 at 13:46
  • @quamrana How I can do this? please you can write a simple explanation with code? Thanks – Com Media Nov 05 '20 at 14:09
  • btw you don't have any threads in your code. – quamrana Nov 05 '20 at 14:31
  • @quamrana I have tried 3 different ways to implement threads in the code, and the result is always exactly the same. That's why I'm asking for an example ... to see what I'm doing wrong ... Thanks for answering – Com Media Nov 05 '20 at 14:33
  • Try [this](https://stackoverflow.com/questions/56117419/running-a-thread-with-tkinter-object/56118993#56118993) example. – quamrana Nov 05 '20 at 14:37
  • Which loop are you talking about? I dont see any `while` loop that stops the GUI from updating, is it the `for` loop? Also, I think `root.after(0, start_ping)` is same as `start_ping()`, you are directly calling the function, without waiting any ms – Delrius Euphoria Nov 05 '20 at 15:11

0 Answers0