Interfaz

parent 916c040a
import paho.mqtt.client as mqtt
class Conexion:
def __init__(self, topics,on_msg):
# Configuración del broker MQTT
self.__broker_address = "192.168.48.245" # Cambia por la dirección de tu broker MQTT
#self.__broker_address = "192.168.0.100" # Cambia por la dirección de tu broker MQTT
self.__port = 1883 # Puerto predeterminado para MQTT
#self.__topic = ["A3-467/GrupoL","map"]
self.__topic = topics
#def on_message(client, userdata, message):
# print("message received " ,str(message.payload.decode("utf-8")))
# print("message topic=",message.topic)
# print("message qos=",message.qos)
# print("message retain flag=",message.retain)
# #self.__listaPendientes.append(f'{message.topic}-{message.payload.decode("utf-8")}')
########################################
#broker_address="192.168.0.19"
#broker_address="iot.eclipse.org"
print("creating new instance")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
#client.on_message = on_message
#client.on_message=on_message #attach function to callback
client.on_message = on_msg
print("connecting to broker")
client.connect(self.__broker_address,self.__port) #connect to broker
client.loop_start() #start the loop
for tp in self.__topic:
client.subscribe(tp)
print(f" Subscrito a {tp}")
#self.__client = self.__connect_mqtt()
#self.inicializar()
#self.__client.loop_start()
#self.subscribe(cliente=client,topic=self.__topic)
self.__client = client
print("Inicializado")
#self.__listaPendientes = listaPendientes
#self.__client.loop_forever()
def publicar(self,topic,msg):
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect(self.__broker_address, self.__port)
result = client.publish(topic,msg)
client.disconnect()
#result = self.__client.publish(self.__topic[0],msg)
# result: [0, 1]
status = result[0]
if status == 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
def desconectar(self):
self.__client.loop_stop()
self.__client.disconnect()
print("Desconectado")
# Función para enviar mensajes MQTT al broker
def send_mqtt_message( topic,message):
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.connect("192.168.0.19" , 1883)
client.publish(topic, message)
client.disconnect()
# def publish(client):
# msg_count = 1
# while True:
# #time.sleep(1)
# msg = f"messages: {msg_count}"
# result = client.publish(topic, msg)
# # result: [0, 1]
# status = result[0]
# if status == 0:
# print(f"Send `{msg}` to topic `{topic}`")
# else:
# print(f"Failed to send message to topic {topic}")
# msg_count += 1
# if msg_count > 5:
# break
#def __subscribe(client: mqtt, topic):
#def run():
# client = connect_mqtt()
# client.loop_start()
# publish(client)
# client.loop_stop()
#def run():
# client = connect_mqtt()
# subscribe(client)
# client.loop_forever()
import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import conexion as cn
import time
# Clase que crea una ventana secundaria con la matriz de botones
class MatrixWindow:
# master: Ventana principal del Tkinter
# matriz: matriz de valores para los botones
# queue_callback: Funcion de callback para manejar los clicks en los botones
def __init__(self, master, matriz, queue_callback):
self.master = tk.Toplevel(master)
self.master.title("Matriz de Botones")
self.matriz = matriz
self.queue_callback = queue_callback
self.click_positions = []
self.load_images()
self.display_buttons()
#Bloquear ventana principal
self.master.grab_set()
# Carga imagenes desde un directorio y las ajusta al tamaño deseado. Si una imagen no se encuentra,
# muestra un mensaje de error y coloca una casilla gris
def load_images(self):
self.images = {}
desired_size = (50, 50)
for i in range(12):
image_number = f"{i:02}"
try:
image = Image.open(f"images/{image_number}.png")
image = image.resize(desired_size, Image.Resampling.LANCZOS)
self.images[image_number] = ImageTk.PhotoImage(image)
except FileNotFoundError:
print(f"Error: No se encontró la imagen para {image_number}")
self.images['default'] = ImageTk.PhotoImage(Image.new('RGB', desired_size, color='grey'))
# Crea botones en la ventana secuandaria usando las imagenes cargadas. Los botones tienen asignados comandos que llaman a 'record_click()'
def display_buttons(self):
for i in range(7):
for j in range(5):
image_value = self.matriz[i][j]
image = self.images.get(image_value, self.images['default'])
if(image_value == '01'):
if(j-1 < 0 or j+1 >4):
btn = tk.Button(self.master, image=image, compound=tk.CENTER, command=lambda i=i, j=j: self.record_click(i, j), bg='#515e5d')
else:
if((self.matriz[i][j-1] != '05' and self.matriz[i][j-1] != '06' and self.matriz[i][j-1] != '10' and self.matriz[i][j-1] != '00') and (self.matriz[i][j+1] != '03' and self.matriz[i][j+1] != '04' and self.matriz[i][j+1] != '08' and self.matriz[i][j+1] != '00') ):
btn = tk.Label(self.master, image=image, compound=tk.CENTER)
else:
btn = tk.Button(self.master, image=image, compound=tk.CENTER, command=lambda i=i, j=j: self.record_click(i, j), bg='#515e5d')
elif(image_value == '02'):
if(i-1 < 0 or i+1 >6):
btn = tk.Button(self.master, image=image, compound=tk.CENTER, command=lambda i=i, j=j: self.record_click(i, j), bg='#515e5d')
else:
if((self.matriz[i-1][j] != '03' and self.matriz[i-1][j] != '06' and self.matriz[i-1][j] != '07' and self.matriz[i-1][j] != '00') and (self.matriz[i+1][j] != '04' and self.matriz[i+1][j] != '05' and self.matriz[i+1][j] != '09' and self.matriz[i+1][j] != '00') ):
btn = tk.Label(self.master, image=image, compound=tk.CENTER)
else:
btn = tk.Button(self.master, image=image, compound=tk.CENTER, command=lambda i=i, j=j: self.record_click(i, j), bg='#515e5d')
else:
btn = tk.Label(self.master, image=image, compound=tk.CENTER)
btn.image = image
btn.grid(row=i, column=j)
# Registra clicks en los botones y, al seleccionar dos botones diferentes,
# llama al callback para actualizar la cola visual y cierra la ventana secuandaria
def record_click(self, i, j):
position = (i, j)
if position not in self.click_positions:
self.click_positions.append(position)
if len(self.click_positions) == 2:
if self.click_positions[0] != self.click_positions[1]:
self.queue_callback(self.click_positions[0], self.click_positions[1])
self.master.destroy()
else:
self.click_positions.pop()
# Clase principal que gestiona la ventana principal de la aplicación
class MainApp:
def __init__(self, master):
self.master = master
master.title("Ventana Principal")
self.left_panel = ttk.Frame(master)
self.left_panel.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.right_panel = ttk.Frame(master)
self.right_panel.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
ttk.Button(self.right_panel, text="Añadir Peticiones", command=self.open_matrix_window).pack(pady=20)
self.queue_listbox = tk.Listbox(self.right_panel, width=40, height=10)
self.queue_listbox.pack(padx=20, pady=20)
self.matriz = self.create_initial_matrix()
self.load_images()
self.labels = {}
self.display_static_matrix()
# Carga imagenes desde un directorio y las ajusta al tamaño deseado. Si una imagen no se encuentra,
# muestra un mensaje de error y coloca una casilla gris
def load_images(self):
self.images = {}
desired_size = (50, 50)
for i in range(12):
image_number = f"{i:02}"
try:
image = Image.open(f"images/{image_number}.png")
image = image.resize(desired_size, Image.Resampling.LANCZOS)
self.images[image_number] = ImageTk.PhotoImage(image)
except FileNotFoundError:
print(f"Error: No se encontró la imagen para {image_number}")
self.images['default'] = ImageTk.PhotoImage(Image.new('RGB', desired_size, color='grey'))
# Muestra una version estática de la matriz en la ventana principal sin funcionalidad
def display_static_matrix(self):
for i in range(7):
for j in range(5):
image_value = self.matriz[i][j]
image = self.images.get(image_value, self.images['default'])
lbl = tk.Label(self.left_panel, image=image, relief='flat')
lbl.image = image
lbl.grid(row=i, column=j)
self.labels[(i, j)] = lbl
# Crea una matriz basada en una cadena codificada que representa valores
def create_initial_matrix(self):
self.cadena = ""
# def on_message(client, userdata, message):
# print(f'Topic:{message.topic} Mensage:{str(message.payload.decode("utf-8"))}')
# if(message.topic == "map"):
# self.cadena = str(message.payload.decode("utf-8"))
# topics = ["A3-467/GrupoL/Interfaz","map"]
# conex = cn.Conexion(topics=topics,on_msg=on_message)
# Pruebas
self.cadena = "0202000105030705000200041109060110031000000200080101100110000106010701"
while(self.cadena == ""):
time.sleep(1)
segmentos = [self.cadena[i:i+2] for i in range(0, len(self.cadena), 2)]
matriz = []
for i in range(7):
fila = segmentos[i*5:(i+1)*5]
matriz.append(fila)
return matriz
# Inicia la ventana secundaria MatrixWindow
def open_matrix_window(self):
MatrixWindow(self.master, self.matriz, self.update_queue_display)
# Inserta un nuevo par origen-destino en la Listbox
def update_queue_display(self, origen, destino):
self.queue_listbox.insert(tk.END, (origen, destino))
self.highlight_path()
# Resalta los botones correspondientes al primer elemento de la Listbox
def highlight_path(self):
# Reset all labels
for label in self.labels.values():
label.config(relief='flat', bg='SystemButtonFace') # Reset all labels
# Highlight only the first item in the queue
if self.queue_listbox.size() > 0:
origen, destino = self.queue_listbox.get(0)
self.labels[origen].config(relief='raised', borderwidth=2, bg='green')
self.labels[destino].config(relief='raised', borderwidth=2, bg='red')
#Inicializa la aplicación
def main():
root = tk.Tk()
app = MainApp(root)
root.mainloop()
if __name__ == "__main__":
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment