Source code for fancywidgets.pyQtBased.FwTabWidget

# -*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore



[docs]class FwTabWidget(QtGui.QTabWidget): ''' * allow to iterate over all tabs using for tab in TabWidget... * allow to give tabs (and not indexes) to: * removeTab * tabText also: interactive... * adding of new tabs, * tab removal * tab renaming ''' sigTabAdded = QtCore.pyqtSignal(object)#tab def __init__(self, defaultTabWidget=QtGui.QWidget): QtGui.QTabWidget.__init__(self) #use lambda to make later overwriting possible: self.tabCloseRequested.connect(lambda index: self.removeTab(index)) self.setTabBar(_TabBar()) self._btn_add_height = None self.defaultTabWidget = defaultTabWidget
[docs] def setTabsRenamable(self, renamable): self.tabBar().tabsRenamable = renamable
[docs] def setTabsAddable(self, addable): if addable: btn = QtGui.QToolButton(self) btn.clicked.connect(lambda checked: self.addEmptyTab()) btn.setIcon(QtGui.QApplication.style().standardIcon(QtGui.QStyle.SP_FileDialogNewFolder)) self.setCornerWidget(btn) self.tabCloseRequested.connect(self._mkAddBtnVisible) self._mkAddBtnVisible() else: btn = self.cornerWidget() if btn: btn.hide() self.tabCloseRequested.disconnect(self._mkAddBtnVisible)
[docs] def addEmptyTab(self, text=''): ''' Add a new DEFAULT_TAB_WIDGET, open editor to set text if no text is given ''' tab = self.defaultTabWidget() c = self.count() self.addTab(tab, text) self.setCurrentIndex (c) if not text: self.tabBar().editTab(c) self.sigTabAdded.emit(tab) return tab
def _mkAddBtnVisible(self): ''' Ensure that the Add button is visible also when there are no tabs ''' if not self._btn_add_height: self._btn_add_height = self.cornerWidget().height() if self.count() == 0: self.cornerWidget().setMinimumHeight(self._btn_add_height-8) self.setMinimumHeight(self._btn_add_height) def __iter__(self): self._i = -1 return self
[docs] def next(self): self._i += 1 if self._i == self.count(): raise StopIteration() return self.widget(self._i)
[docs] def widgetByName(self, name): for i in range(self.count()): if self.tabText(i)==name: return self.widet(i)
[docs] def removeTab(self, tab): '''allows to remove a tab directly -not only by giving its index''' if type(tab) != int: tab = self.indexOf(tab) return super(FwTabWidget, self).removeTab(tab)
[docs] def tabText(self,tab): ''' allow index or tab widget instance''' if type(tab) != int: tab = self.indexOf(tab) return super(FwTabWidget, self).tabText(tab)
class _TabBar(QtGui.QTabBar): ''' allow change of tabTitle via double click ''' def __init__(self, parent=None): QtGui.QTabBar.__init__(self, parent) self.tabsRenamable = False self._editor = QtGui.QLineEdit(self) self._editor.setWindowFlags(QtCore.Qt.Popup) self._editor.setFocusProxy(self) self._editor.editingFinished.connect(self.handleEditingFinished) self._editor.installEventFilter(self) def eventFilter(self, widget, event): if ((event.type() == QtCore.QEvent.MouseButtonPress and not self._editor.geometry().contains(event.globalPos())) or (event.type() == QtCore.QEvent.KeyPress and event.key() == QtCore.Qt.Key_Escape)): self._editor.hide() return True return QtGui.QTabBar.eventFilter(self, widget, event) def mouseDoubleClickEvent(self, event): if self.tabsRenamable: index = self.tabAt(event.pos()) if index >= 0: self.editTab(index) def editTab(self, index): rect = self.tabRect(index) self._editor.setFixedSize(rect.size()) self._editor.move(self.parent().mapToGlobal(rect.topLeft())) self._editor.setText(self.tabText(index)) if not self._editor.isVisible(): self._editor.show() def handleEditingFinished(self): index = self.currentIndex() if index >= 0: self._editor.hide() self.setTabText(index, self._editor.text()) if __name__ == '__main__': import sys app = QtGui.QApplication(sys.argv) w = FwTabWidget() w.setWindowTitle(w.__class__.__name__) #switching on/off/on w.setTabsAddable(True) w.setTabsClosable(True) w.setTabsRenamable(True) w.setTabsAddable(False) w.setTabsClosable(False) w.setTabsRenamable(False) w.setTabsAddable(True) w.setTabsClosable(True) w.setTabsRenamable(True) w.show() app.exec_()