Coverage for graphica/gui/shell/rail.py: 94.9%
66 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 16:38 +0000
1"""左端のアイコンの帯。押すと左パネルのページを替える。下にはダークモードと設定。"""
2from PySide6.QtCore import QSize, Qt, Signal
3from PySide6.QtWidgets import QButtonGroup, QToolButton, QVBoxLayout, QWidget
5from graphica.gui.shell.icons import checkable_icon, themed_icon
7RAIL_WIDTH = 56
8RAIL_BUTTON_SIZE = 38
11def _rail_button(icon_name, tooltip, checkable):
12 button = QToolButton()
13 button.setObjectName("rail_button")
14 button.setToolTip(tooltip)
15 button.setCheckable(checkable)
16 button.setFixedSize(RAIL_BUTTON_SIZE, RAIL_BUTTON_SIZE)
17 button.setIconSize(QSize(20, 20))
18 button.setFocusPolicy(Qt.FocusPolicy.NoFocus)
19 button.setCursor(Qt.CursorShape.PointingHandCursor)
20 button.setProperty("iconName", icon_name)
21 return button
24class ActivityRail(QWidget):
25 page_requested = Signal(str)
27 def __init__(self, parent=None):
28 super().__init__(parent)
29 self.setObjectName("activity_rail")
30 self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
31 self.setFixedWidth(RAIL_WIDTH)
32 layout = QVBoxLayout(self)
33 layout.setContentsMargins(9, 8, 9, 8)
34 layout.setSpacing(4)
35 self._group = QButtonGroup(self)
36 self._group.setExclusive(True)
37 self._page_buttons = {}
38 self._top_count = 0
39 layout.addStretch(1)
41 def add_page(self, key, icon_name, tooltip):
42 """上の並びにページのボタンを足す。最初のものを選んだ状態にする。"""
43 button = _rail_button(icon_name, tooltip, checkable=True)
44 button.setIcon(checkable_icon(icon_name))
45 button.clicked.connect(lambda _checked=False, k=key: self.select_page(k))
46 self._group.addButton(button)
47 self.layout().insertWidget(self._top_count, button, 0, Qt.AlignmentFlag.AlignHCenter)
48 self._top_count += 1
49 self._page_buttons[key] = button
50 if len(self._page_buttons) == 1:
51 button.setChecked(True)
52 return button
54 def add_bottom_button(self, icon_name, tooltip, slot):
55 button = _rail_button(icon_name, tooltip, checkable=False)
56 button.setIcon(themed_icon(icon_name, size=20))
57 button.clicked.connect(slot)
58 self.layout().addWidget(button, 0, Qt.AlignmentFlag.AlignHCenter)
59 return button
61 def page_button(self, key):
62 return self._page_buttons.get(key)
64 def current_page(self):
65 for key, button in self._page_buttons.items(): 65 ↛ 68line 65 didn't jump to line 68 because the loop on line 65 didn't complete
66 if button.isChecked():
67 return key
68 return None
70 def select_page(self, key):
71 button = self._page_buttons[key]
72 if not button.isChecked():
73 button.setChecked(True)
74 self.page_requested.emit(key)
76 def refresh_icons(self):
77 for button in self.findChildren(QToolButton, "rail_button"):
78 name = button.property("iconName")
79 if not name: 79 ↛ 80line 79 didn't jump to line 80 because the condition on line 79 was never true
80 continue
81 button.setIcon(checkable_icon(name) if button.isCheckable() else themed_icon(name, size=20))