QTabBar/QTabWidget 中的选项卡内联重命名
Inline renaming of a tab in QTabBar/QTabWidget
我真的很想有一个 QTabWidget,可以在选项卡标题上通过 double-click 重命名。
我用谷歌搜索并找到了 this solution,但它更像是一个大纲,供开发人员使用 Qt 并对其小部件进行子类化。
我有点不知道如何实现所有这些。我已经使用了 example given further down that thread(与 IndependentLineEdit
等)并且它有效,但这不是我想要的。
我不想有任何类型的 InputDialog。我不想有任何浮动小部件或其他东西。
我基本上想要的是使用 QTabWidget(子类),它的行为方式与现代办公套件中电子表格选项卡的行为类似 - 例如,选项卡标签被无缝行编辑所取代,这会在 Enter 上重置选项卡标签或在 Esc 上保持原样。
到目前为止,我还没有找到这样的解决方案。我明白我真正需要的是非常接近这个:
provide a temporary QLineEdit at QTabBar::tabRect() filled with QTabBar::tabText()
但我不知道该怎么做。此外,由于 QTabBar 是一种裸标签栏,我也希望将其包含在 QTabWidget(子类)中。
以下是 PyQt4 Python 中此类行为的实现。将其转换为 C++ 应该很容易。请注意,Qt5 有一个很好的信号 tabBarDoubleClicked,而 Qt4 中没有。这段代码也产生了这样的信号。
from PyQt4 import QtGui
from PyQt4.QtCore import pyqtSignal, pyqtSlot
class QTabBar(QtGui.QTabBar):
"""QTabBar with double click signal and tab rename behavior."""
def __init__(self, parent=None):
super().__init__(parent)
tabDoubleClicked = pyqtSignal(int)
def mouseDoubleClickEvent(self, event):
tab_index = self.tabAt(event.pos())
self.tabDoubleClicked.emit(tab_index)
self.start_rename(tab_index)
def start_rename(self, tab_index):
self.__edited_tab = tab_index
rect = self.tabRect(tab_index)
top_margin = 3
left_margin = 6
self.__edit = QtGui.QLineEdit(self)
self.__edit.show()
self.__edit.move(rect.left() + left_margin, rect.top() + top_margin)
self.__edit.resize(rect.width() - 2 * left_margin, rect.height() - 2 * top_margin)
self.__edit.setText(self.tabText(tab_index))
self.__edit.selectAll()
self.__edit.setFocus()
self.__edit.editingFinished.connect(self.finish_rename)
@pyqtSlot()
def finish_rename(self):
self.setTabText(self.__edited_tab, self.__edit.text())
self.__edit.deleteLater()
class QTabWidget(QtGui.QTabWidget):
"""QTabWidget with double click on tab signal and tab rename behavior."""
def __init__(self, parent):
super().__init__(parent)
self.setTabBar(QTabBar())
self.tabBar().tabDoubleClicked.connect(self.tabBarDoubleClicked)
tabBarDoubleClicked = pyqtSignal(int)
请注意,在选项卡 header 中对齐 qlineedit 有一个相当老套的解决方案。它是通过将保证金固定为某个值来实现的。我敢肯定,如有必要,可以在样式中查找该值。
我真的很想有一个 QTabWidget,可以在选项卡标题上通过 double-click 重命名。
我用谷歌搜索并找到了 this solution,但它更像是一个大纲,供开发人员使用 Qt 并对其小部件进行子类化。
我有点不知道如何实现所有这些。我已经使用了 example given further down that thread(与 IndependentLineEdit
等)并且它有效,但这不是我想要的。
我不想有任何类型的 InputDialog。我不想有任何浮动小部件或其他东西。
我基本上想要的是使用 QTabWidget(子类),它的行为方式与现代办公套件中电子表格选项卡的行为类似 - 例如,选项卡标签被无缝行编辑所取代,这会在 Enter 上重置选项卡标签或在 Esc 上保持原样。
到目前为止,我还没有找到这样的解决方案。我明白我真正需要的是非常接近这个:
provide a temporary QLineEdit at QTabBar::tabRect() filled with QTabBar::tabText()
但我不知道该怎么做。此外,由于 QTabBar 是一种裸标签栏,我也希望将其包含在 QTabWidget(子类)中。
以下是 PyQt4 Python 中此类行为的实现。将其转换为 C++ 应该很容易。请注意,Qt5 有一个很好的信号 tabBarDoubleClicked,而 Qt4 中没有。这段代码也产生了这样的信号。
from PyQt4 import QtGui
from PyQt4.QtCore import pyqtSignal, pyqtSlot
class QTabBar(QtGui.QTabBar):
"""QTabBar with double click signal and tab rename behavior."""
def __init__(self, parent=None):
super().__init__(parent)
tabDoubleClicked = pyqtSignal(int)
def mouseDoubleClickEvent(self, event):
tab_index = self.tabAt(event.pos())
self.tabDoubleClicked.emit(tab_index)
self.start_rename(tab_index)
def start_rename(self, tab_index):
self.__edited_tab = tab_index
rect = self.tabRect(tab_index)
top_margin = 3
left_margin = 6
self.__edit = QtGui.QLineEdit(self)
self.__edit.show()
self.__edit.move(rect.left() + left_margin, rect.top() + top_margin)
self.__edit.resize(rect.width() - 2 * left_margin, rect.height() - 2 * top_margin)
self.__edit.setText(self.tabText(tab_index))
self.__edit.selectAll()
self.__edit.setFocus()
self.__edit.editingFinished.connect(self.finish_rename)
@pyqtSlot()
def finish_rename(self):
self.setTabText(self.__edited_tab, self.__edit.text())
self.__edit.deleteLater()
class QTabWidget(QtGui.QTabWidget):
"""QTabWidget with double click on tab signal and tab rename behavior."""
def __init__(self, parent):
super().__init__(parent)
self.setTabBar(QTabBar())
self.tabBar().tabDoubleClicked.connect(self.tabBarDoubleClicked)
tabBarDoubleClicked = pyqtSignal(int)
请注意,在选项卡 header 中对齐 qlineedit 有一个相当老套的解决方案。它是通过将保证金固定为某个值来实现的。我敢肯定,如有必要,可以在样式中查找该值。