Skip to content
Snippets Groups Projects
Commit fc32908d authored by mhby1g21's avatar mhby1g21
Browse files

refactoring to use PyQt6, starting with config tab

parent 837f339a
No related branches found
No related tags found
1 merge request!4GDP 4.2.10 - Adding Debug mode to GUI.py to run individual modules
import tkinter as tk from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTabWidget
from tkinter import ttk import sys
import os import os
from tabs.config_tab import ConfigTab from tabs.config_tab import ConfigTab
from tabs.shifter_tab import ShifterTab
from tabs.depth_tab import DepthTab
from tabs.material_tab import MaterialTab
from tabs.edge_net_tab import EdgeNetTab
from utils.config_reader import ConfigReader from utils.config_reader import ConfigReader
class ModuleDebugGUI: class ModuleDebugGUI(QMainWindow):
def __init__(self): def __init__(self):
self.window = tk.Tk() super().__init__()
self.window.title("Pipeline Debug Tool") self.setWindowTitle("Pipeline Debug Tool")
self.window.geometry("1600x800") self.setGeometry(100, 100, 1600, 800)
# Initialize paths # Initialize paths
self.DEBUG_DIR = os.path.dirname(os.path.abspath(__file__)) # debug_tool directory self.DEBUG_DIR = os.path.dirname(os.path.abspath(__file__)) # debug_tool directory
...@@ -23,21 +19,27 @@ class ModuleDebugGUI: ...@@ -23,21 +19,27 @@ class ModuleDebugGUI:
# Read configuration # Read configuration
self.config_reader = ConfigReader(self.DEBUG_DIR, self.ROOT_DIR) self.config_reader = ConfigReader(self.DEBUG_DIR, self.ROOT_DIR)
# Create notebook for tabs # Setup UI
self.notebook = ttk.Notebook(self.window) self.setup_ui()
self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# Initialize tabs def setup_ui(self):
self.config_tab = ConfigTab(self.notebook, self.config_reader) # Create main widget and layout
self.shifter_tab = ShifterTab(self.notebook, self.config_reader) main_widget = QWidget()
self.depth_tab = DepthTab(self.notebook, self.config_reader) self.setCentralWidget(main_widget)
self.material_tab = MaterialTab(self.notebook, self.config_reader) layout = QVBoxLayout(main_widget)
self.edge_net_tab = EdgeNetTab(self.notebook, self.config_reader)
# Create tab widget
self.tabs = QTabWidget()
layout.addWidget(self.tabs)
# Initialize tabs
self.tabs.addTab(ConfigTab(self.config_reader), "Configuration")
def run(self): def main():
self.window.mainloop() app = QApplication(sys.argv)
window = ModuleDebugGUI()
window.show()
sys.exit(app.exec())
if __name__ == "__main__": if __name__ == "__main__":
app = ModuleDebugGUI() main()
app.run() \ No newline at end of file
\ No newline at end of file
import tkinter as tk # tabs/config_tab.py
from tkinter import ttk, messagebox from PyQt6.QtWidgets import QWidget, QVBoxLayout, QMessageBox
from PyQt6.QtGui import QTextCharFormat, QColor, QTextCursor
from utils.qt_widgets import create_group_with_text, create_button_layout
import os import os
class ConfigTab: class ConfigTab(QWidget):
def __init__(self, notebook, config_reader): def __init__(self, config_reader):
self.tab = ttk.Frame(notebook) super().__init__()
notebook.add(self.tab, text='Configuration Check')
self.config_reader = config_reader self.config_reader = config_reader
self.setup_ui() self.setup_ui()
def setup_ui(self): def setup_ui(self):
# Main container with padding main_layout = QVBoxLayout(self)
main_frame = ttk.Frame(self.tab, padding="10") main_layout.setContentsMargins(10, 10, 10, 10)
main_frame.pack(fill=tk.BOTH, expand=True)
# Create groups and text areas using the utility function
# Config section config_group, self.config_text = create_group_with_text("Config Values", 100)
config_frame = ttk.LabelFrame(main_frame, text="Config Values", padding="5") dir_group, self.dir_text = create_group_with_text("Directory Paths", 120)
config_frame.pack(fill=tk.X, pady=5) file_group, self.file_text = create_group_with_text("File Paths", 80)
verify_group, self.verify_text = create_group_with_text("Path Verification", 120)
self.config_text = tk.Text(config_frame, height=6, wrap=tk.WORD)
self.config_text.pack(fill=tk.X) # Add groups to layout
main_layout.addWidget(config_group)
# Directory paths section main_layout.addWidget(dir_group)
dir_frame = ttk.LabelFrame(main_frame, text="Directory Paths", padding="5") main_layout.addWidget(file_group)
dir_frame.pack(fill=tk.X, pady=5) main_layout.addWidget(verify_group)
self.dir_text = tk.Text(dir_frame, height=8, wrap=tk.WORD) # Create buttons using the utility function
self.dir_text.pack(fill=tk.X) buttons = [
("Refresh Config", self.refresh_all, 'left'),
# File paths section ("Verify Paths", self.verify_paths, 'left'),
file_frame = ttk.LabelFrame(main_frame, text="File Paths", padding="5") ("Save Debug Info", self.save_debug_info, 'right')
file_frame.pack(fill=tk.X, pady=5) ]
button_layout = create_button_layout(*buttons)
self.file_text = tk.Text(file_frame, height=5, wrap=tk.WORD) main_layout.addLayout(button_layout)
self.file_text.pack(fill=tk.X)
# Path verification section
verify_frame = ttk.LabelFrame(main_frame, text="Path Verification", padding="5")
verify_frame.pack(fill=tk.X, pady=5)
self.verify_text = tk.Text(verify_frame, height=8, wrap=tk.WORD)
self.verify_text.pack(fill=tk.X)
# Buttons
button_frame = ttk.Frame(main_frame)
button_frame.pack(fill=tk.X, pady=5)
ttk.Button(
button_frame,
text="Refresh Config",
command=self.refresh_all
).pack(side=tk.LEFT, padx=5)
ttk.Button(
button_frame,
text="Verify Paths",
command=self.verify_paths
).pack(side=tk.LEFT, padx=5)
ttk.Button(
button_frame,
text="Save Debug Info",
command=self.save_debug_info
).pack(side=tk.RIGHT, padx=5)
# Initial display # Initial display
self.refresh_all() self.refresh_all()
def refresh_all(self): def refresh_all(self):
self.refresh_config_display() self.display_config()
self.refresh_directory_display() self.display_directories()
self.refresh_file_display() self.display_files()
self.verify_paths() self.verify_paths()
def refresh_config_display(self): def display_config(self):
self.config_text.delete(1.0, tk.END) self.config_text.clear()
for key, value in self.config_reader.config.items(): for key, value in self.config_reader.config.items():
self.config_text.insert(tk.END, f"{key} = {value}\n") self.config_text.append(f"{key} = {value}")
def refresh_directory_display(self): def display_directories(self):
self.dir_text.delete(1.0, tk.END) self.dir_text.clear()
for key, path in self.config_reader.directories.items(): for key, path in self.config_reader.directories.items():
self.dir_text.insert(tk.END, f"{key}: {path}\n") self.dir_text.append(f"{key}: {path}")
def refresh_file_display(self): def display_files(self):
self.file_text.delete(1.0, tk.END) self.file_text.clear()
for key, path in self.config_reader.file_paths.items(): for key, path in self.config_reader.file_paths.items():
self.file_text.insert(tk.END, f"{key}: {path}\n") self.file_text.append(f"{key}: {path}")
def verify_paths(self): def verify_paths(self):
self.verify_text.delete(1.0, tk.END) self.verify_text.clear()
# Create formats for colored text
green_format = QTextCharFormat()
green_format.setForeground(QColor("green"))
red_format = QTextCharFormat()
red_format.setForeground(QColor("red"))
# Verify directories self.verify_text.append("Directory Verification:")
self.verify_text.insert(tk.END, "Directory Verification:\n")
for key, path in self.config_reader.directories.items(): for key, path in self.config_reader.directories.items():
exists = os.path.exists(path) exists = os.path.exists(path)
status = "✓ exists" if exists else "✗ missing" status = "✓ exists" if exists else "✗ missing"
color = "green" if exists else "red" cursor = self.verify_text.textCursor()
self.verify_text.insert(tk.END, f"{key}: {status}\n", color) cursor.movePosition(QTextCursor.MoveOperation.End)
self.verify_text.setTextCursor(cursor)
self.verify_text.insert(tk.END, "\nFile Verification:\n") self.verify_text.insertPlainText(f"{key}: ")
self.verify_text.setCurrentCharFormat(green_format if exists else red_format)
self.verify_text.insertPlainText(f"{status}\n")
self.verify_text.setCurrentCharFormat(QTextCharFormat())
self.verify_text.append("\nFile Verification:")
for key, path in self.config_reader.file_paths.items(): for key, path in self.config_reader.file_paths.items():
exists = os.path.exists(path) exists = os.path.exists(path)
status = "✓ exists" if exists else "✗ missing" status = "✓ exists" if exists else "✗ missing"
color = "green" if exists else "red" cursor = self.verify_text.textCursor()
self.verify_text.insert(tk.END, f"{key}: {status}\n", color) cursor.movePosition(QTextCursor.MoveOperation.End)
self.verify_text.setTextCursor(cursor)
# Add tags for colors self.verify_text.insertPlainText(f"{key}: ")
self.verify_text.tag_config("green", foreground="green") self.verify_text.setCurrentCharFormat(green_format if exists else red_format)
self.verify_text.tag_config("red", foreground="red") self.verify_text.insertPlainText(f"{status}\n")
def save_debug_info(self): def save_debug_info(self):
debug_info = "=== Pipeline Debug Information ===\n\n" debug_info = "=== Pipeline Debug Information ===\n\n"
...@@ -130,13 +110,13 @@ class ConfigTab: ...@@ -130,13 +110,13 @@ class ConfigTab:
status = "exists" if exists else "missing" status = "exists" if exists else "missing"
debug_info += f"{key}: {path} ({status})\n" debug_info += f"{key}: {path} ({status})\n"
# Save to debug tool directory
try: try:
debug_path = os.path.join(self.config_reader.directories['debugDir'], debug_path = os.path.join(self.config_reader.directories['debugDir'],
"pipeline_debug_info.txt") "debug_config_info.txt")
with open(debug_path, "w") as f: with open(debug_path, "w") as f:
f.write(debug_info) f.write(debug_info)
messagebox.showinfo("Success", QMessageBox.information(self, "Success",
f"Debug information saved to:\n{debug_path}") f"Debug information saved to:\n{debug_path}")
except Exception as e: except Exception as e:
messagebox.showerror("Error", f"Failed to save debug info: {str(e)}") QMessageBox.critical(self, "Error",
\ No newline at end of file f"Failed to save debug info: {str(e)}")
\ No newline at end of file
# utils/file_handlers.py
from PyQt6.QtWidgets import QFileDialog
def select_file(parent, title="Select File", file_types="All Files (*)", initial_dir=""):
"""
Opens a file selection dialog.
Args:
parent: Parent widget
title: Dialog window title
file_types: File filter (e.g., "Images (*.png *.jpg);;All Files (*)")
initial_dir: Starting directory for the dialog
Returns:
Selected file path or empty string if cancelled
"""
file_path, _ = QFileDialog.getOpenFileName(
parent,
title,
initial_dir,
file_types
)
return file_path
def save_file(parent, title="Save File", file_types="All Files (*)", initial_dir="", suggested_name=""):
"""
Opens a save file dialog.
Args:
parent: Parent widget
title: Dialog window title
file_types: File filter
initial_dir: Starting directory
suggested_name: Default filename
Returns:
Selected save path or empty string if cancelled
"""
file_path, _ = QFileDialog.getSaveFileName(
parent,
title,
os.path.join(initial_dir, suggested_name),
file_types
)
return file_path
def select_directory(parent, title="Select Directory", initial_dir=""):
"""
Opens a directory selection dialog.
Args:
parent: Parent widget
title: Dialog window title
initial_dir: Starting directory
Returns:
Selected directory path or empty string if cancelled
"""
return QFileDialog.getExistingDirectory(
parent,
title,
initial_dir,
QFileDialog.Option.ShowDirsOnly
)
from PyQt6.QtGui import QPixmap, QImage
import numpy as np
import cv2
def convert_cv_to_pixmap(cv_img):
height, width = cv_img.shape[:2]
if len(cv_img.shape) == 3:
bytes_per_line = 3 * width
qt_img = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format.Format_RGB888)
else:
bytes_per_line = width
qt_img = QImage(cv_img.data, width, height, bytes_per_line, QImage.Format.Format_Grayscale8)
return QPixmap.fromImage(qt_img)
def load_and_resize_image(image_path, max_size=800):
try:
img = cv2.imread(image_path)
if img is None:
raise Exception("Failed to load image")
# Convert to RGB
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Calculate resize ratio
height, width = img.shape[:2]
ratio = min(max_size/width, max_size/height)
if ratio < 1:
new_size = (int(width * ratio), int(height * ratio))
img = cv2.resize(img, new_size, interpolation=cv2.INTER_AREA)
return img
except Exception as e:
raise Exception(f"Error loading image: {str(e)}")
\ No newline at end of file
from PIL import Image, ImageTk
import os
def create_preview(image_path, size=(300, 300)):
"""Create a thumbnail preview of the given image"""
try:
if not os.path.exists(image_path):
raise FileNotFoundError(f"Image file not found: {image_path}")
img = Image.open(image_path)
img.thumbnail(size)
return ImageTk.PhotoImage(img)
except Exception as e:
raise Exception(f"Failed to create image preview: {str(e)}")
def verify_image(image_path):
"""Verify that an image file exists and can be opened"""
try:
if not os.path.exists(image_path):
return False
Image.open(image_path)
return True
except:
return False
\ No newline at end of file
# utils/qt_widgets.py
from PyQt6.QtWidgets import (QTextEdit, QGroupBox, QVBoxLayout,
QHBoxLayout, QPushButton)
def create_group_with_text(title, height=100):
"""
Creates a QGroupBox containing a QTextEdit.
Args:
title: Group box title
height: Fixed height for text edit
Returns:
tuple: (QGroupBox, QTextEdit)
"""
group = QGroupBox(title)
layout = QVBoxLayout(group)
text_edit = QTextEdit()
text_edit.setFixedHeight(height)
text_edit.setReadOnly(True)
layout.addWidget(text_edit)
return group, text_edit
def create_button_layout(*buttons):
"""
Creates a horizontal button layout with optional stretch.
Args:
buttons: List of tuples (label, callback, position)
position can be 'left', 'right', or None for default
Returns:
QHBoxLayout with arranged buttons
"""
layout = QHBoxLayout()
# Add left-aligned buttons
for label, callback, position in buttons:
if position == 'left':
btn = QPushButton(label)
btn.clicked.connect(callback)
layout.addWidget(btn)
# Add stretch in the middle
layout.addStretch()
# Add right-aligned buttons
for label, callback, position in buttons:
if position == 'right':
btn = QPushButton(label)
btn.clicked.connect(callback)
layout.addWidget(btn)
return layout
def create_status_group():
"""
Creates a standard status display group.
Returns:
tuple: (QGroupBox, QTextEdit)
"""
return create_group_with_text("Status", 80)
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment