diff --git a/main_window.py b/main_window.py index 90af296..dedecbf 100644 --- a/main_window.py +++ b/main_window.py @@ -3,7 +3,7 @@ from copy import deepcopy from pathlib import Path import sys -from PySide6.QtCore import QEvent, QSignalBlocker, QSize, Qt +from PySide6.QtCore import QEvent, QSignalBlocker, QSize, Qt, QTimer from PySide6.QtGui import QAction, QColor, QImageReader, QKeySequence from PySide6.QtWidgets import ( QAbstractItemView, @@ -224,6 +224,7 @@ class MainWindow(QMainWindow): self.sidebar_tab_container: SidebarTab | None = None self._sidebar_collapsed = False self._sidebar_last_width = SIDEBAR_DEFAULT_WIDTH + self.menu_buttons_widget: QWidget | None = None self.canvas = LedCanvas() self._apply_canvas_settings() @@ -493,23 +494,28 @@ class MainWindow(QMainWindow): tools_menu.addSeparator() tools_menu.addAction(self.actions["brush"]) - # Add vertical separator and buttons next to the menu headers in the QMenuBar - container = QWidget() - layout = QHBoxLayout(container) - layout.setContentsMargins(10, 0, 10, 0) + # Delete old widget if recreating + if hasattr(self, "menu_buttons_widget") and self.menu_buttons_widget is not None: + self.menu_buttons_widget.deleteLater() + self.menu_buttons_widget = None + + # Add vertical separator and buttons next to the menu headers in the QMenuBar as a child overlay + self.menu_buttons_widget = QWidget(menu_bar) + layout = QHBoxLayout(self.menu_buttons_widget) + layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(4) # Vertical line separator - separator = QFrame() + separator = QFrame(self.menu_buttons_widget) separator.setFrameShape(QFrame.Shape.VLine) separator.setFrameShadow(QFrame.Shadow.Sunken) - separator.setStyleSheet("color: #cbd5e1; margin: 4px 0;") + separator.setStyleSheet("color: #cbd5e1; margin: 2px 0;") layout.addWidget(separator) # Add Tools actions as buttons for key in ["add_line", "add_led", "generate_script", "auto_blocks", "counterclockwise", "brush"]: action = self.actions[key] - btn = QToolButton() + btn = QToolButton(self.menu_buttons_widget) btn.setDefaultAction(action) btn.setIconSize(QSize(16, 16)) btn.setToolButtonStyle(Qt.ToolButtonIconOnly) @@ -517,9 +523,26 @@ class MainWindow(QMainWindow): btn.setStyleSheet("QToolButton { border: none; padding: 2px; }") layout.addWidget(btn) - widget_action = QWidgetAction(menu_bar) - widget_action.setDefaultWidget(container) - menu_bar.addAction(widget_action) + self.menu_buttons_widget.show() + QTimer.singleShot(0, self._reposition_menu_buttons) + + def resizeEvent(self, event) -> None: + super().resizeEvent(event) + self._reposition_menu_buttons() + + def _reposition_menu_buttons(self) -> None: + if not hasattr(self, "menu_buttons_widget") or self.menu_buttons_widget is None: + return + menu_bar = self.menuBar() + actions = menu_bar.actions() + if len(actions) < 4: + return + tools_action = actions[3] + rect = menu_bar.actionGeometry(tools_action) + if rect.isValid() and rect.right() > 0: + h = menu_bar.height() + w = self.menu_buttons_widget.sizeHint().width() + self.menu_buttons_widget.setGeometry(rect.right() + 10, (h - 20) // 2, w, 20) def _build_layout(self) -> None: side = QWidget() diff --git a/qa_smoke.py b/qa_smoke.py index 6256168..fc6487c 100644 --- a/qa_smoke.py +++ b/qa_smoke.py @@ -1194,14 +1194,10 @@ def test_menu_bar_tools_buttons() -> None: window = MainWindow() app.processEvents() - # Find the QWidgetAction in the QMenuBar - from PySide6.QtWidgets import QWidgetAction, QToolButton, QFrame - menu_bar = window.menuBar() - widget_actions = [action for action in menu_bar.actions() if isinstance(action, QWidgetAction)] - assert len(widget_actions) == 1 - - container = widget_actions[0].defaultWidget() + from PySide6.QtWidgets import QToolButton, QFrame + container = window.menu_buttons_widget assert container is not None + assert container.parent() == window.menuBar() # Check layout layout = container.layout()