У меня ошибка в коде, нажимаю кнопку "Вернуть", интерфейс вылетает, интерфейс в TKINTERPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 У меня ошибка в коде, нажимаю кнопку "Вернуть", интерфейс вылетает, интерфейс в TKINTER

Сообщение Anonymous »

Я пробовал разные способы, но у меня это не сработало, я разместил несколько отпечатков, чтобы лучше определить, где возникла ошибка, и оказалось, что она остается по адресу: [Ventana3] Finalizando hilo...
вот мой код:

Код: Выделить всё

import tkinter as tk
from tkinter import ttk
import cv2
from threading import Thread
from ultralytics import YOLO
from PIL import Image, ImageTk
from tkinter import messagebox
import numpy as np
from threading import Event

Model = YOLO("Modelo_v5m.pt")

class Ventana3:
def __init__(self, master, cam_indices, on_regresar):
print("[Ventana3] Inicializando...")
self.root = master
self.on_regresar = lambda: self.before_on_regresar(on_regresar)
self.selected_cameras_indices = cam_indices
self.stop_event = Event()
self.setup_window3()

def setup_window3(self):
print("[Ventana3] Configurando ventana...")
self.root.title("Visualización de Cámaras")
self.root.geometry("880x700")
self.camera_frames = []
self.root.protocol("WM_DELETE_WINDOW", self.on_close_window)

# Crear un frame principal para usar pack
main_frame = tk.Frame(self.root)
main_frame.pack(fill=tk.BOTH, expand=True)

# Iniciar captura de video para las cámaras seleccionadas
self.cap = [cv2.VideoCapture(i) for i in self.selected_cameras_indices]

for i, cap in enumerate(self.cap):
print(f"[Ventana3] Cap {i} iniciado: {cap.isOpened()}")

# Cálculo dinámico de columnas y tamaño de frames
num_camaras = len(self.cap)
cols = round(num_camaras ** 0.5)
rows = (num_camaras // cols) + (num_camaras % cols > 0)

for i in range(num_camaras):
camera_frame = tk.Label(main_frame)
camera_frame.grid(row=i // cols, column=i % cols, sticky='nsew')
main_frame.grid_columnconfigure(i % cols, weight=1)
main_frame.grid_rowconfigure(i // cols, weight=1)
self.camera_frames.append(camera_frame)

ttk.Button(self.root, text="Regresar", width=20, command=self.on_regresar).place(x=15, y=15) #boton regresar a la ventana 2

self.stop_event.clear()

# Iniciar el proceso de actualización de las cámaras en un hilo separado
print("[Ventana3] Iniciando hilo de captura de video...")
self.thread = Thread(target=self.start_camera_streams)
self.thread.daemon = True
self.thread.start()

def before_on_regresar(self, on_regresar):
print("[Ventana3] Botón Regresar presionado, iniciando limpieza...")
self.clear_window()
on_regresar()

def start_camera_streams(self):
print("[Ventana3] Captura de video iniciada.")
while not self.stop_event.is_set():
for i, cap in enumerate(self.cap):
ret, frame = cap.read()
if ret:
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Convertir el frame de BGR (OpenCV) a RGB
resultados = Model.predict(frame_rgb) # Procesar el frame con el modelo
anotaciones = resultados[0].plot()   # YOLOv8 espera una lista de imágenes
img = Image.fromarray(anotaciones)
photo = ImageTk.PhotoImage(image=img)
self.update_camera_frame(i, photo)
print("Captura de video detenida.")

def update_camera_frame(self, index, photo):
if index <  len(self.camera_frames):
camera_frame = self.camera_frames[index]
if camera_frame.winfo_exists():  # Comprueba si el widget aún existe
camera_frame.configure(image=photo)
camera_frame.image = photo

def clear_window(self):
print("[Ventana3] Deteniendo hilo y liberando cámaras...")
self.stop_event.set()  # Indica al hilo que debe detenerse
self.root.after(100, self.final_cleanup)

def final_cleanup(self): # Detener el hilo de actualización de la cámara
print("[Ventana3] Finalizando hilo...")
if hasattr(self, 'thread'):
self.thread.join()
print("[Ventana3] Hilo finalizado.")

print("[Ventana3] Liberando cámaras...")
if hasattr(self, 'cap'):  # Comprueba si self.cap tiene cámaras abiertas para liberar
for i, cap in enumerate(self.cap):
cap.release()
print(f"[Ventana3] Cámara {i} liberada.")

print("[Ventana3] Limpiando widgets...")
for widget in self.root.winfo_children(): # Limpiar los widgets de la ventana
widget.destroy()
print("[Ventana3] Limpieza de widgets finalizada.")

def on_close_window(self):
print("[Ventana3] Cerrando ventana...")
self.clear_window()
self.root.destroy()
Кроме того, код моего main.py, где я управляю действиями кнопок:

Код: Выделить всё

import tkinter as tk
from Ventana1 import Ventana1
from Ventana2 import Ventana2
from Ventana3 import Ventana3

class MainApp:
def __init__(self, root):
# Initialize the MainApp class with the root tkinter window
self.root = root
self.current_window = None
self.goto_window1()

def clear_window(self):
# Remove all widgets from the root window
for widget in self.root.winfo_children():
widget.destroy()

def goto_window1(self):
# Clear the current window and go to Ventana1
self.clear_window()
self.current_window = Ventana1(self.root, lambda: self.navigate("Ventana2"))

def goto_window2(self):
# Clear the current window and go to Ventana2
self.clear_window()
self.current_window = Ventana2(self.root, self.navigate)

#manejar acciones de los botones
def navigate(self, action, cam_indices=None):
if action == "CONFIRMAR": # Solo navega a la ventana 3 si hay cámaras seleccionadas
self.goto_window3(cam_indices)
elif action == "REGRESAR":
self.goto_window1()
elif action == "Ventana2":
self.goto_window2()
elif action == "Ventana3":
self.goto_window3()

def goto_window2_from_window3(self): #llamar a clear_window para limpiar recursos de Ventana3
if self.current_window and hasattr(self.current_window, 'clear_window'):
self.current_window.clear_window()
self.goto_window2()

def goto_window3(self, cam_indices=None):
# Clear the current window and go to Ventana3
self.clear_window()
self.current_window = Ventana3(self.root, cam_indices, self.goto_window2_from_window3)

def end_app(self):
# Close the root window and end the application
self.root.destroy()

if __name__ == "__main__":
# Create the root tkinter window
root = tk.Tk()
# Create an instance of the MainApp class
app = MainApp(root)
# Start the tkinter event loop
root.mainloop()
Я попробовал несколько вещей, и я надеюсь, что потоки камеры закрываются правильно, и когда я нажимаю кнопку возврата, я перехожу в окно 2

Подробнее здесь: https://stackoverflow.com/questions/782 ... crashes-in
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»