Fix QMenuBar tools buttons rendering using child widget overlay
- Исправлено отображение кнопок инструментов в QMenuBar: вместо QWidgetAction использован дочерний виджет QWidget с абсолютным позиционированием. - Добавлено позиционирование виджета кнопок справа от заголовка Инструменты с автоматическим пересчетом координат в resizeEvent. - Обновлен юнит-тест test_menu_bar_tools_buttons под новое представление.
This commit is contained in:
parent
3431ef6b50
commit
5507d1c7c7
@ -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()
|
||||
|
||||
10
qa_smoke.py
10
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()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user