Adding splitter and saving layout state when closing the app
This commit is contained in:
@@ -13,7 +13,7 @@ from PySide6.QtWidgets import (
|
||||
QVBoxLayout,
|
||||
QLabel,
|
||||
)
|
||||
from PySide6.QtCore import Qt, QTimer
|
||||
from PySide6.QtCore import Qt, QTimer, QSettings
|
||||
from PySide6.QtGui import QAction, QKeySequence
|
||||
|
||||
from src.database.db_manager import DatabaseManager
|
||||
@@ -52,8 +52,8 @@ class MainWindow(QMainWindow):
|
||||
self._create_tab_widget()
|
||||
self._create_status_bar()
|
||||
|
||||
# Center window on screen
|
||||
self._center_window()
|
||||
# Restore window geometry or center window on screen
|
||||
self._restore_window_state()
|
||||
|
||||
logger.info("Main window initialized")
|
||||
|
||||
@@ -156,6 +156,24 @@ class MainWindow(QMainWindow):
|
||||
(screen.width() - size.width()) // 2, (screen.height() - size.height()) // 2
|
||||
)
|
||||
|
||||
def _restore_window_state(self):
|
||||
"""Restore window geometry from settings or center window."""
|
||||
settings = QSettings("microscopy_app", "object_detection")
|
||||
geometry = settings.value("main_window/geometry")
|
||||
|
||||
if geometry:
|
||||
self.restoreGeometry(geometry)
|
||||
logger.debug("Restored window geometry from settings")
|
||||
else:
|
||||
self._center_window()
|
||||
logger.debug("Centered window on screen")
|
||||
|
||||
def _save_window_state(self):
|
||||
"""Save window geometry to settings."""
|
||||
settings = QSettings("microscopy_app", "object_detection")
|
||||
settings.setValue("main_window/geometry", self.saveGeometry())
|
||||
logger.debug("Saved window geometry to settings")
|
||||
|
||||
def _show_settings(self):
|
||||
"""Show settings dialog."""
|
||||
logger.info("Opening settings dialog")
|
||||
@@ -276,6 +294,13 @@ class MainWindow(QMainWindow):
|
||||
)
|
||||
|
||||
if reply == QMessageBox.Yes:
|
||||
# Save window state before closing
|
||||
self._save_window_state()
|
||||
|
||||
# Save annotation tab state if it exists
|
||||
if hasattr(self, "annotation_tab"):
|
||||
self.annotation_tab.save_state()
|
||||
|
||||
logger.info("Application closing")
|
||||
event.accept()
|
||||
else:
|
||||
|
||||
@@ -12,6 +12,7 @@ from PySide6.QtWidgets import (
|
||||
QPushButton,
|
||||
QFileDialog,
|
||||
QMessageBox,
|
||||
QSplitter,
|
||||
)
|
||||
from PySide6.QtCore import Qt, QSettings
|
||||
from pathlib import Path
|
||||
@@ -43,25 +44,13 @@ class AnnotationTab(QWidget):
|
||||
"""Setup user interface."""
|
||||
layout = QVBoxLayout()
|
||||
|
||||
# Image loading section
|
||||
load_group = QGroupBox("Image Loading")
|
||||
load_layout = QVBoxLayout()
|
||||
# Main horizontal splitter to divide left (image) and right (controls)
|
||||
self.main_splitter = QSplitter(Qt.Horizontal)
|
||||
self.main_splitter.setHandleWidth(10)
|
||||
|
||||
# Load image button
|
||||
button_layout = QHBoxLayout()
|
||||
self.load_image_btn = QPushButton("Load Image")
|
||||
self.load_image_btn.clicked.connect(self._load_image)
|
||||
button_layout.addWidget(self.load_image_btn)
|
||||
button_layout.addStretch()
|
||||
|
||||
load_layout.addLayout(button_layout)
|
||||
|
||||
# Image info label
|
||||
self.image_info_label = QLabel("No image loaded")
|
||||
load_layout.addWidget(self.image_info_label)
|
||||
|
||||
load_group.setLayout(load_layout)
|
||||
layout.addWidget(load_group)
|
||||
# { Left splitter for image display and zoom info
|
||||
self.left_splitter = QSplitter(Qt.Vertical)
|
||||
self.left_splitter.setHandleWidth(10)
|
||||
|
||||
# Image display section
|
||||
display_group = QGroupBox("Image Display")
|
||||
@@ -73,7 +62,21 @@ class AnnotationTab(QWidget):
|
||||
display_layout.addWidget(self.image_display_widget)
|
||||
|
||||
display_group.setLayout(display_layout)
|
||||
layout.addWidget(display_group)
|
||||
self.left_splitter.addWidget(display_group)
|
||||
|
||||
# Zoom controls info
|
||||
zoom_info = QLabel("Zoom: Mouse wheel or +/- keys to zoom in/out")
|
||||
zoom_info.setStyleSheet("QLabel { color: #888; font-style: italic; }")
|
||||
self.left_splitter.addWidget(zoom_info)
|
||||
# }
|
||||
|
||||
# { Right splitter for annotation tools and controls
|
||||
self.right_splitter = QSplitter(Qt.Vertical)
|
||||
self.right_splitter.setHandleWidth(10)
|
||||
|
||||
# Image loading section
|
||||
load_group = QGroupBox("Image Loading")
|
||||
load_layout = QVBoxLayout()
|
||||
|
||||
# Future features info
|
||||
info_group = QGroupBox("Annotation Tool (Future Feature)")
|
||||
@@ -86,18 +89,41 @@ class AnnotationTab(QWidget):
|
||||
"- Export annotations to YOLO format\n"
|
||||
"- Annotation verification"
|
||||
)
|
||||
info_label.setWordWrap(True)
|
||||
info_layout.addWidget(info_label)
|
||||
info_group.setLayout(info_layout)
|
||||
|
||||
layout.addWidget(info_group)
|
||||
self.right_splitter.addWidget(info_group)
|
||||
|
||||
# Zoom controls info
|
||||
zoom_info = QLabel("Zoom: Mouse wheel or +/- keys to zoom in/out")
|
||||
zoom_info.setStyleSheet("QLabel { color: #888; font-style: italic; }")
|
||||
layout.addWidget(zoom_info)
|
||||
# Load image button
|
||||
button_layout = QHBoxLayout()
|
||||
self.load_image_btn = QPushButton("Load Image")
|
||||
self.load_image_btn.clicked.connect(self._load_image)
|
||||
button_layout.addWidget(self.load_image_btn)
|
||||
button_layout.addStretch()
|
||||
load_layout.addLayout(button_layout)
|
||||
|
||||
# Image info label
|
||||
self.image_info_label = QLabel("No image loaded")
|
||||
load_layout.addWidget(self.image_info_label)
|
||||
|
||||
load_group.setLayout(load_layout)
|
||||
self.right_splitter.addWidget(load_group)
|
||||
# }
|
||||
|
||||
# Add both splitters to the main horizontal splitter
|
||||
self.main_splitter.addWidget(self.left_splitter)
|
||||
self.main_splitter.addWidget(self.right_splitter)
|
||||
|
||||
# Set initial sizes: 75% for left (image), 25% for right (controls)
|
||||
self.main_splitter.setSizes([750, 250])
|
||||
|
||||
layout.addWidget(self.main_splitter)
|
||||
self.setLayout(layout)
|
||||
|
||||
# Restore splitter positions from settings
|
||||
self._restore_state()
|
||||
|
||||
def _load_image(self):
|
||||
"""Load and display an image file."""
|
||||
# Get last opened directory from QSettings
|
||||
@@ -171,6 +197,49 @@ class AnnotationTab(QWidget):
|
||||
"""Handle zoom level changes from the image display widget."""
|
||||
self._update_image_info()
|
||||
|
||||
def _restore_state(self):
|
||||
"""Restore splitter positions from settings."""
|
||||
settings = QSettings("microscopy_app", "object_detection")
|
||||
|
||||
# Restore main splitter state
|
||||
main_state = settings.value("annotation_tab/main_splitter_state")
|
||||
if main_state:
|
||||
self.main_splitter.restoreState(main_state)
|
||||
logger.debug("Restored main splitter state")
|
||||
|
||||
# Restore left splitter state
|
||||
left_state = settings.value("annotation_tab/left_splitter_state")
|
||||
if left_state:
|
||||
self.left_splitter.restoreState(left_state)
|
||||
logger.debug("Restored left splitter state")
|
||||
|
||||
# Restore right splitter state
|
||||
right_state = settings.value("annotation_tab/right_splitter_state")
|
||||
if right_state:
|
||||
self.right_splitter.restoreState(right_state)
|
||||
logger.debug("Restored right splitter state")
|
||||
|
||||
def save_state(self):
|
||||
"""Save splitter positions to settings."""
|
||||
settings = QSettings("microscopy_app", "object_detection")
|
||||
|
||||
# Save main splitter state
|
||||
settings.setValue(
|
||||
"annotation_tab/main_splitter_state", self.main_splitter.saveState()
|
||||
)
|
||||
|
||||
# Save left splitter state
|
||||
settings.setValue(
|
||||
"annotation_tab/left_splitter_state", self.left_splitter.saveState()
|
||||
)
|
||||
|
||||
# Save right splitter state
|
||||
settings.setValue(
|
||||
"annotation_tab/right_splitter_state", self.right_splitter.saveState()
|
||||
)
|
||||
|
||||
logger.debug("Saved annotation tab splitter states")
|
||||
|
||||
def refresh(self):
|
||||
"""Refresh the tab."""
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user