Título: Refresco tkinter de texto recibido en un callback
Publicado por: minak en 11 Mayo 2018, 11:58 am
Hola estoy haciendo un pequeño programa en python que escucha un servidor mqtt y lo muestra en pantalla en el modo consola no tengo problema pero quise poner una gui con tkinter y no se como hacer que cuando el callback de mensaje recibido refresque un text que esta dentro de una clase que corresponde a la ventana principal. Me podéis ayudar a ver como puedo hacerlo por que es lo unico que me falta y no se me ocurre. Ventana Principal class MyApp: def __init__(self, parent): self.parent = parent self.parent.protocol("WM_DELETE_WINDOW", self.on_closing) #Indicas que cuando presiones la x de cerrar ventana
#Ventana principal root.title(proyect +" "+ version) root.resizable (True, True) root.iconbitmap('pyc.ico') #root.geometry ("650x400") root.config (bg="black",bd="10", relief ="sunken")
ventanainfo = Frame() ventanainfo.grid() #ventanainfo.config (bg="white", width ="630", height ="380", bd="10", relief ="sunken", cursor ="pirate") ventanainfo.config (bg="white", bd="10", relief ="sunken", cursor ="arrow")
#Configuracion de elemetos sobre frame Principal #*****PANTALLA LOG************** pantallaLOG = Text(ventanainfo, width ="90", height ="18") pantallaLOG.grid (row="0", column ="0", padx=1,pady=1,rowspan=4) scrollLog = Scrollbar (ventanainfo, command = pantallaLOG.yview) scrollLog.grid (row="0", column ="1", padx=1,pady=1, sticky = "nSeW",rowspan=4) pantallaLOG.config (yscrollcommand = scrollLog.set)
pantallaLOG.insert(INSERT, 'test.\n') global ultimoMensaje; pantallaLOG.insert(INSERT, ultimoMensaje +'\n')
Callback def on_message(client, userdata, msg): global ultimoMensaje ultimoMensaje = (time.strftime("%d/%m/%y - %H:%M -> ")+"[" + msg.topic+"] "+str(msg.payload)) print (ultimoMensaje)
Dejo el main desde el que se inician callback if __name__ == "__main__":
openConfig();
myIP = getipextern() print (myIP)
client = mqtt.Client(client_name) client.username_pw_set(user, password=password) client.on_connect = on_connect client.on_disconnect = on_disconnect client.on_publish = on_publish client.on_message = on_message #client.on_log = on_log # Descomenta para activar el modo Debug client.on_subscribe = on_subscribe # Callback de una supcripcion
#Comienzo del GUI de usuario
root = tk.Tk() app = MyApp(root) #****Bucle********************** root.mainloop()
#*** Salida del programa print("Cerrando...") try: client.disconnect() client.loop_stop() except: print ("No procede desconectar") print ("Adios") El programa es mucho mas grande pero es que son mas de 500 lineas para ponerlo aqui. Lo que quiero conseguir es que ese cuadro sea como una consola donde se vaya escribiendo lo que pasa en el programa. Muchas gracias
Título: Re: Refresco tkinter de texto recibido en un callback
Publicado por: minak en 11 Mayo 2018, 13:48 pm
Encontre una solucion pero no la entiendo y no es la mejor opcion porque me crea una ventana trasera que entiendo que es para hacer un bucle de refresco el caso que pongo lo que modifique. Esta parte no entiendo porque se tiene que hacer asi pero si no lo hago asi after no me deja usarla dentro de la funcion. class MyApp(tk.Tk): def __init__(self, parent, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs)
y añado esta funcion def update_logtext(self): if (ultimoMensaje!=""):
global ultimoMensaje; self.pantallaLOG.insert(INSERT, ultimoMensaje +'\n') ultimoMensaje =""
self.after(1000, self.update_logtext)
Ahora mientras encuentro otra solucion voy a ver si consigo que la ventana secundaria que se crea sea invisible. PD : Hecho invisible pero no comprendo muy bien todo esto que hize class MyApp(tk.Frame): def __init__(self, parent): tk.Frame.__init__(self) Os pongo el codigo del que saque la solucion por si alguien lo quiere : import Tkinter as tk import time
class SampleApp(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) self.clock = tk.Label(self, text="") self.clock.pack()
# start the clock "ticking" self.update_clock()
def update_clock(self): now = time.strftime("%H:%M:%S" , time.gmtime()) self.clock.configure(text=now) # call this function again in one second self.after(1000, self.update_clock)
if __name__== "__main__": app = SampleApp() app.mainloop()
|