1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
from PyQt5.QtWidgets import QTabBar, QPushButton, QTabWidget, QInputDialog
from PyQt5.QtCore import pyqtSignal, QSize, Qt
class TabBarPlus(QTabBar):
"""
Just implemented to overload resize and layout change to emit a signal and change tab names.
"""
layoutChanged = pyqtSignal()
nameChanged = pyqtSignal(int, str)
def resizeEvent(self, event):
super().resizeEvent(event)
self.layoutChanged.emit()
def tabLayoutChange(self):
super().tabLayoutChange()
self.layoutChanged.emit()
def mouseDoubleClickEvent(self, event):
# tab name change request
if event.button() != Qt.LeftButton:
return super().mouseDoubleClickEvent()
index = self.currentIndex()
newName, bool = QInputDialog.getText(self, "Change Diagram Name", "Enter new name",
text = self.tabText(index))
if bool:
self.setTabText(index, newName)
self.nameChanged.emit(index, newName)
class CustomTabWidget(QTabWidget):
"""
QTabWidget with a new tab button, also catches layoutChange signal by
the TabBarPlus to dynamically move the button to the correct location
"""
plusClicked = pyqtSignal()
def __init__(self, parent=None):
super(CustomTabWidget, self).__init__(parent)
self.tab = TabBarPlus()
self.setTabBar(self.tab) #set tabBar to our custom TabBarPlus
self.plusButton = QPushButton('+', self) #create the new tab button
#style the new tab button
self.plusButton.setFlat(True)
#and parent it to the widget to add it at 0, 0
self.plusButton.setFixedSize(25, 25) #set dimensions
self.plusButton.clicked.connect(self.plusClicked.emit) #emit signal on click
#set flags
self.setMovable(True)
self.setTabsClosable(True)
self.tab.layoutChanged.connect(self.movePlusButton) #connect layout change
# to dynamically move the button.
self.tab.nameChanged.connect(self.changeWidgetName)
#set custom stylesheet for the widget area
def movePlusButton(self):
#move the new tab button to correct location
size = sum([self.tab.tabRect(i).width() for i in range(self.tab.count())])
# calculate width of all tabs
h = max(self.tab.geometry().bottom() - self.plusButton.height(), 0) #align with bottom of tabbar
w = self.tab.width()
if size > w: #if all the tabs do not overflow the tab bar, add at the end
self.plusButton.move(w-self.plusButton.width(), h)
else:
self.plusButton.move(size+5, h)
def changeWidgetName(self, index, newName):
self.widget(index).setObjectName(newName)
|