Coverage for graphica/gui/shell/project_tabs.py: 94.3%

64 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-12 16:38 +0000

1"""プロジェクトのタブ。タブの帯は上部バーに置き、中身(各タブの PlotterApp)はその下に重ねる。 

2 

3QTabWidget は帯と中身を1つの部品に持つので、帯だけを上部バーへ移せない。今まで QTabWidget で使っていた呼び方 

4(addTab・removeTab・widget・indexOf・count・currentIndex・tabText など)はそのまま使える。 

5""" 

6from PySide6.QtCore import Qt, Signal 

7from PySide6.QtWidgets import QStackedWidget, QTabBar, QVBoxLayout, QWidget 

8 

9 

10class ProjectTabs(QWidget): 

11 currentChanged = Signal(int) 

12 tabCloseRequested = Signal(int) 

13 

14 def __init__(self, parent=None): 

15 super().__init__(parent) 

16 self._bar = QTabBar() 

17 self._bar.setObjectName("project_tab_bar") 

18 self._bar.setDrawBase(False) 

19 self._bar.setExpanding(False) 

20 self._bar.setElideMode(Qt.TextElideMode.ElideRight) 

21 self._bar.setUsesScrollButtons(True) 

22 self._bar.setFocusPolicy(Qt.FocusPolicy.NoFocus) 

23 self._stack = QStackedWidget(self) 

24 layout = QVBoxLayout(self) 

25 layout.setContentsMargins(0, 0, 0, 0) 

26 layout.addWidget(self._stack) 

27 self._bar.currentChanged.connect(self._on_bar_current_changed) 

28 self._bar.tabCloseRequested.connect(self.tabCloseRequested) 

29 self._bar.tabMoved.connect(self._on_tab_moved) 

30 

31 def tabBar(self): 

32 return self._bar 

33 

34 def _on_bar_current_changed(self, index): 

35 if 0 <= index < self._stack.count(): 35 ↛ 37line 35 didn't jump to line 37 because the condition on line 35 was always true

36 self._stack.setCurrentIndex(index) 

37 self.currentChanged.emit(index) 

38 

39 def _on_tab_moved(self, from_index, to_index): 

40 widget = self._stack.widget(from_index) 

41 self._stack.removeWidget(widget) 

42 self._stack.insertWidget(to_index, widget) 

43 self._stack.setCurrentIndex(self._bar.currentIndex()) 

44 

45 def addTab(self, widget, text): 

46 # 先に中身を足す(帯に足した時点で currentChanged が出て、その先が中身を引く) 

47 self._stack.addWidget(widget) 

48 return self._bar.addTab(text) 

49 

50 def removeTab(self, index): 

51 if not 0 <= index < self._stack.count(): 51 ↛ 52line 51 didn't jump to line 52 because the condition on line 51 was never true

52 return 

53 self._stack.removeWidget(self._stack.widget(index)) 

54 self._bar.removeTab(index) 

55 

56 def widget(self, index): 

57 return self._stack.widget(index) 

58 

59 def indexOf(self, widget): 

60 return self._stack.indexOf(widget) 

61 

62 def count(self): 

63 return self._bar.count() 

64 

65 def currentIndex(self): 

66 return self._bar.currentIndex() 

67 

68 def setCurrentIndex(self, index): 

69 self._bar.setCurrentIndex(index) 

70 

71 def currentWidget(self): 

72 return self._stack.currentWidget() 

73 

74 def setCurrentWidget(self, widget): 

75 index = self.indexOf(widget) 

76 if index >= 0: 76 ↛ exitline 76 didn't return from function 'setCurrentWidget' because the condition on line 76 was always true

77 self.setCurrentIndex(index) 

78 

79 def tabText(self, index): 

80 return self._bar.tabText(index) 

81 

82 def setTabText(self, index, text): 

83 self._bar.setTabText(index, text) 

84 

85 def setTabsClosable(self, closable): 

86 self._bar.setTabsClosable(closable) 

87 

88 def setMovable(self, movable): 

89 self._bar.setMovable(movable)