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 tkinter import ttk
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QTabWidget
import sys
import os
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
class ModuleDebugGUI:
class ModuleDebugGUI(QMainWindow):
def __init__(self):
self.window = tk.Tk()
self.window.title("Pipeline Debug Tool")
self.window.geometry("1600x800")
super().__init__()
self.setWindowTitle("Pipeline Debug Tool")
self.setGeometry(100, 100, 1600, 800)
# Initialize paths
self.DEBUG_DIR = os.path.dirname(os.path.abspath(__file__)) # debug_tool directory
......@@ -23,21 +19,27 @@ class ModuleDebugGUI:
# Read configuration
self.config_reader = ConfigReader(self.DEBUG_DIR, self.ROOT_DIR)
# Create notebook for tabs
self.notebook = ttk.Notebook(self.window)
self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# Setup UI
self.setup_ui()
# Initialize tabs
self.config_tab = ConfigTab(self.notebook, self.config_reader)
self.shifter_tab = ShifterTab(self.notebook, self.config_reader)
self.depth_tab = DepthTab(self.notebook, self.config_reader)
self.material_tab = MaterialTab(self.notebook, self.config_reader)
self.edge_net_tab = EdgeNetTab(self.notebook, self.config_reader)
def setup_ui(self):
# Create main widget and layout
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
# Create tab widget
self.tabs = QTabWidget()
layout.addWidget(self.tabs)
# Initialize tabs
self.tabs.addTab(ConfigTab(self.config_reader), "Configuration")
def run(self):
self.window.mainloop()
def main():
app = QApplication(sys.argv)
window = ModuleDebugGUI()
window.show()
sys.exit(app.exec())
if __name__ == "__main__":
app = ModuleDebugGUI()
app.run()
\ No newline at end of file
main()
\ No newline at end of file
import tkinter as tk
from tkinter import ttk, messagebox
# tabs/config_tab.py
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
class ConfigTab:
def __init__(self, notebook, config_reader):
self.tab = ttk.Frame(notebook)
notebook.add(self.tab, text='Configuration Check')
class ConfigTab(QWidget):
def __init__(self, config_reader):
super().__init__()
self.config_reader = config_reader
self.setup_ui()
def setup_ui(self):
# Main container with padding
main_frame = ttk.Frame(self.tab, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# Config section
config_frame = ttk.LabelFrame(main_frame, text="Config Values", padding="5")
config_frame.pack(fill=tk.X, pady=5)
self.config_text = tk.Text(config_frame, height=6, wrap=tk.WORD)
self.config_text.pack(fill=tk.X)
# Directory paths section
dir_frame = ttk.LabelFrame(main_frame, text="Directory Paths", padding="5")
dir_frame.pack(fill=tk.X, pady=5)
self.dir_text = tk.Text(dir_frame, height=8, wrap=tk.WORD)
self.dir_text.pack(fill=tk.X)
# File paths section
file_frame = ttk.LabelFrame(main_frame, text="File Paths", padding="5")
file_frame.pack(fill=tk.X, pady=5)
self.file_text = tk.Text(file_frame, height=5, wrap=tk.WORD)
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)
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(10, 10, 10, 10)
# Create groups and text areas using the utility function
config_group, self.config_text = create_group_with_text("Config Values", 100)
dir_group, self.dir_text = create_group_with_text("Directory Paths", 120)
file_group, self.file_text = create_group_with_text("File Paths", 80)
verify_group, self.verify_text = create_group_with_text("Path Verification", 120)
# Add groups to layout
main_layout.addWidget(config_group)
main_layout.addWidget(dir_group)
main_layout.addWidget(file_group)
main_layout.addWidget(verify_group)
# Create buttons using the utility function
buttons = [
("Refresh Config", self.refresh_all, 'left'),
("Verify Paths", self.verify_paths, 'left'),
("Save Debug Info", self.save_debug_info, 'right')
]
button_layout = create_button_layout(*buttons)
main_layout.addLayout(button_layout)
# Initial display
self.refresh_all()
def refresh_all(self):
self.refresh_config_display()
self.refresh_directory_display()
self.refresh_file_display()
self.display_config()
self.display_directories()
self.display_files()
self.verify_paths()
def refresh_config_display(self):
self.config_text.delete(1.0, tk.END)
def display_config(self):
self.config_text.clear()
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):
self.dir_text.delete(1.0, tk.END)
def display_directories(self):
self.dir_text.clear()
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):
self.file_text.delete(1.0, tk.END)
def display_files(self):
self.file_text.clear()
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):
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.insert(tk.END, "Directory Verification:\n")
self.verify_text.append("Directory Verification:")
for key, path in self.config_reader.directories.items():
exists = os.path.exists(path)
status = "✓ exists" if exists else "✗ missing"
color = "green" if exists else "red"
self.verify_text.insert(tk.END, f"{key}: {status}\n", color)
self.verify_text.insert(tk.END, "\nFile Verification:\n")
cursor = self.verify_text.textCursor()
cursor.movePosition(QTextCursor.MoveOperation.End)
self.verify_text.setTextCursor(cursor)
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():
exists = os.path.exists(path)
status = "✓ exists" if exists else "✗ missing"
color = "green" if exists else "red"
self.verify_text.insert(tk.END, f"{key}: {status}\n", color)
# Add tags for colors
self.verify_text.tag_config("green", foreground="green")
self.verify_text.tag_config("red", foreground="red")
cursor = self.verify_text.textCursor()
cursor.movePosition(QTextCursor.MoveOperation.End)
self.verify_text.setTextCursor(cursor)
self.verify_text.insertPlainText(f"{key}: ")
self.verify_text.setCurrentCharFormat(green_format if exists else red_format)
self.verify_text.insertPlainText(f"{status}\n")
def save_debug_info(self):
debug_info = "=== Pipeline Debug Information ===\n\n"
......@@ -130,13 +110,13 @@ class ConfigTab:
status = "exists" if exists else "missing"
debug_info += f"{key}: {path} ({status})\n"
# Save to debug tool directory
try:
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:
f.write(debug_info)
messagebox.showinfo("Success",
QMessageBox.information(self, "Success",
f"Debug information saved to:\n{debug_path}")
except Exception as e:
messagebox.showerror("Error", f"Failed to save debug info: {str(e)}")
\ No newline at end of file
QMessageBox.critical(self, "Error",
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