¿Cómo puede actualizar un GUI con información de una función o archivo adyacente?
Estoy tratando de crear un panel sensor que actualiza cada segundo o dos que dibuja información de Open Hardware Monitor. He creado una función que produce una lista de valores relacionados con la información deseada, sin embargo no puedo conseguir que actualice el GUI. Esta es una versión reducida que sólo muestra la temperatura del paquete CPU. Se mostrará el valor inicial cuando se ejecute, pero no se actualizará. Planeo crear un archivo ejecutable de este código que se puede ejecutar en una pantalla terciaria para dar estadísticas constantes en mi computadora.
import tkinter as tk
import wmi as w
root = tk.Tk()
i=0
def initialize():
def update():
w1 = w.WMI(namespace="root\OpenHardwareMonitor")
temperature_infos = w1.Sensor()
names = ['CPU Package' , 'GPU Core', 'CPU Total']
values = [0.0 , 0.0, 0.0, 0.0, 0.0,0.0,0.0,0.0,0.0]
for sensor in temperature_infos:
if sensor.SensorType == u'Temperature':
if sensor.Name == names[0]:
values[0] = sensor.Value
elif sensor.Name == names[1]:
values[1] = sensor.Value
else:
pass
elif sensor.SensorType == u'Load':
if sensor.Name == names[2]:
values[2] = sensor.Value
elif sensor.Name == names[1]:
values[3] = sensor.Value
elif sensor.Name == u'GPU Memory':
values[4] = sensor.Value
elif sensor.Name == u'Memory':
values[5] = sensor.Value
else:
pass
elif sensor.SensorType == u'Clock':
if sensor.Name == u'CPU Core #8':
values[6] = sensor.Value
else:
pass
elif sensor.SensorType == u'Fan':
if sensor.Name == u'Fan #5':
values[7] = sensor.Value
elif sensor.Name == u'GPU Fan':
values[8] = sensor.Value
else:
pass
return values
values = update()
text = tk.StringVar()
text.set(values[0])
label1 = tk.Label(root, textvariable = text)
global i
if i == 0:
label1.pack()
i+=1
else:
label1.config(textvariable = text)
root.after(1000,initialize)
root.after(1000,initialize)
root.mainloop()
Pregunta hecha hace 3 años, 5 meses, 0 días - Por binarymaestro
3 Respuestas:
-
No uso Windows así que no puedo usar el módulo
wmi
pero en cuanto a mí debe ser:Yo creo vacío
Label
sólo una vez - al principio - y usoafter(1000, update)
para ejecutar función que obtiene valores deget_values()
y actualiza el texto en la etiquetalabel.config(text=...)
. No crea nuevoLabel
, No tiene que comprobar si necesitapack
oconfig
. No necesitaStringVar
(pero francamente podría usarlo y entonces no necesitaríalabel.config
)import tkinter as tk import wmi as w # --- functions ---- def get_values(): w1 = w.WMI(namespace="root\OpenHardwareMonitor") temperature_infos = w1.Sensor() names = ['CPU Package' , 'GPU Core', 'CPU Total'] values = [0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] for sensor in temperature_infos: if sensor.SensorType == u'Temperature': if sensor.Name == names[0]: values[0] = sensor.Value elif sensor.Name == names[1]: values[1] = sensor.Value #else: # pass elif sensor.SensorType == u'Load': if sensor.Name == names[2]: values[2] = sensor.Value elif sensor.Name == names[1]: values[3] = sensor.Value elif sensor.Name == u'GPU Memory': values[4] = sensor.Value elif sensor.Name == u'Memory': values[5] = sensor.Value #else: # pass elif sensor.SensorType == u'Clock': if sensor.Name == u'CPU Core #8': values[6] = sensor.Value #else: # pass elif sensor.SensorType == u'Fan': if sensor.Name == u'Fan #5': values[7] = sensor.Value elif sensor.Name == u'GPU Fan': values[8] = sensor.Value #else: # pass return values def update(): values = get_values() label.config(text=values[0]) root.after(1000, update) # --- main --- root = tk.Tk() label = tk.Label(root) label.pack(padx=20, pady=20) root.after(1000, update) root.mainloop()
Versión que emula cambios en
values
y todo el mundo puede correrimport tkinter as tk # --- functions ---- def get_values(): import random values = [0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] values[0] = random.randrange(0, 1000)/10 # float value 0.0 ... 100.0 return values def update(): values = get_values() label.config(text=values[0]) root.after(1000, update) # --- main --- root = tk.Tk() label = tk.Label(root) label.pack(padx=20, pady=20) root.after(1000, update) root.mainloop()
EDIT:
Lo mismo con
StringVar()
en lugar delabel.config(text=...)
import tkinter as tk # --- functions ---- def get_values(): import random values = [0.0 , 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] values[0] = random.randrange(0, 1000)/10 return values def update(): values = get_values() label_var.set(values[0]) root.after(1000, update) # --- main --- root = tk.Tk() label_var = tk.StringVar() # to keep value as string #label_var = tk.IntVar() # to keep value as integer #label_var = tk.DoubleVar() # to keep value as float label = tk.Label(root, textvariable=label_var) label.pack(padx=20, pady=20) root.after(1000, update) root.mainloop()
Respondida el Dec 17, 2020 a las 01:29 - por webweaverx
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando se debe a que estás creando una nueva instancia de
label1
en cada llamada a la funcióninitialize
, lo cual provoca que se añadan nuevos labels en lugar de actualizar el existente. Para solucionar esto, debes crear el label fuera de la funcióninitialize
y luego actualizar su texto en lugar de crear uno nuevo en cada iteración.Aquí te dejo una versión corregida de tu código:
python import tkinter as tk import wmi as w root = tk.Tk() label1 = tk.Label(root) label1.pack() names = ['CPU Package' , 'GPU Core', 'CPU Total'] values = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] def update(): w1 = w.WMI(namespace="root\OpenHardwareMonitor") temperature_infos = w1.Sensor() for sensor in temperature_infos: if sensor.SensorType == u'Temperature': if sensor.Name == names[0]: values[0] = sensor.Value text.set(values[0]) root.after(1000, update) def initialize(): global text text = tk.StringVar() label1.config(textvariable=text) update() initialize() root.mainloop()
En este código, creamos el label
label1
fuera de la funcióninitialize
y lo actualizamos directamente dentro de la funciónupdate
. Además, inicializamos el label con un textvariabletext
y actualizamos este textvariable en cada iteración para reflejar el valor actualizado de la temperatura del paquete CPU. Finalmente, llamamos ainitialize
una sola vez al inicio y luego la funciónupdate
se encarga de manejar la actualización del GUI cada segundo.Respondida el Dec 18, 2020 a las 01:29 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
La función
update
no está siendo llamada periódicamente para actualizar los valores del GUI. Para actualizar el GUI con los nuevos valores, debes llamar aupdate
cada segundo o dos y luego actualizar el valor delStringVar
que está vinculado a laLabel
. Aquí tienes el código modificado:python import tkinter as tk import wmi as w root = tk.Tk() i = 0 def initialize(): def update(): w1 = w.WMI(namespace="root\\OpenHardwareMonitor") temperature_infos = w1.Sensor() names = ['CPU Package' , 'GPU Core', 'CPU Total'] values = [0.0 , 0.0, 0.0, 0.0, 0.0,0.0,0.0,0.0,0.0] for sensor in temperature_infos: if sensor.SensorType == u'Temperature': if sensor.Name == names[0]: values[0] = sensor.Value elif sensor.Name == names[1]: values[1] = sensor.Value else: pass elif sensor.SensorType == u'Load': if sensor.Name == names[2]: values[2] = sensor.Value elif sensor.Name == names[1]: values[3] = sensor.Value elif sensor.Name == u'GPU Memory': values[4] = sensor.Value elif sensor.Name == u'Memory': values[5] = sensor.Value else: pass elif sensor.SensorType == u'Clock': if sensor.Name == u'CPU Core
8':
values[6] = sensor.Value else: pass elif sensor.SensorType == u'Fan': if sensor.Name == u'Fan5':
values[7] = sensor.Value elif sensor.Name == u'GPU Fan': values[8] = sensor.Value else: pass return values values = update() text = tk.StringVar() text.set(values[0]) label1 = tk.Label(root, textvariable=text) global i if i == 0: label1.pack() i += 1 else: label1.config(textvariable=text) root.after(1000, initialize) root.after(1000, update)Llama a update cada segundo
root.after(1000, initialize) root.mainloop()También he eliminado la parte donde configurabas el
StringVar
dentro del bloqueif i == 0
. Esto no es necesario ya que el valor delStringVar
se actualiza cada vez que se llama aupdate
.Respondida el Dec 18, 2020 a las 01:36 - por Gemini
Votos positivos: 0 | Votos negativos: 0