我可以通过编程方式重命名选项卡标签。
使用
QInputDialog
我可以获取新的标签文本并设置选项卡小部件标签。
但是,我希望有一个更加用户友好的解决方案,例如双击标签并在选项卡本身上进行编辑。
带有可编辑标志的
QListWidgetItem
可以为我指明方向,但我找不到选项卡标签的解决方案。
没有内置方法可以实现此目的。但是,您可以使用简单的弹出行编辑并将其放置在选项卡上。这是一个基本的演示脚本:
PyQt5:
import sys
from PyQt5 import QtCore, QtWidgets
class TabBar(QtWidgets.QTabBar):
def __init__(self, parent):
super().__init__(parent)
self._editor = QtWidgets.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 super().eventFilter(widget, event)
def mouseDoubleClickEvent(self, event):
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())
class Window(QtWidgets.QTabWidget):
def __init__(self):
super().__init__()
self.setTabBar(TabBar(self))
self.addTab(QtWidgets.QWidget(self), 'Tab One')
self.addTab(QtWidgets.QWidget(self), 'Tab Two')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setWindowTitle('Test')
window.setGeometry(600, 100, 200, 100)
window.show()
sys.exit(app.exec_())
PyQt4:
from PyQt4 import QtGui, QtCore
class TabBar(QtGui.QTabBar):
def __init__(self, parent):
QtGui.QTabBar.__init__(self, parent)
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):
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())
class Window(QtGui.QTabWidget):
def __init__(self):
QtGui.QTabWidget.__init__(self)
self.setTabBar(TabBar(self))
self.addTab(QtGui.QWidget(self), 'Tab One')
self.addTab(QtGui.QWidget(self), 'Tab Two')
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setWindowTitle('Test')
window.setGeometry(600, 100, 200, 100)
window.show()
sys.exit(app.exec_())
更新 ekhumoro 留下的答案:
在 PyQt5 中,代码现在如下所示:
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtWidgets import QTabBar, QTabWidget, QApplication, QLineEdit, QWidget
class EditableTabBar(QTabBar):
def __init__(self, parent):
QTabBar.__init__(self, parent)
self._editor = QLineEdit(self)
self._editor.setWindowFlags(Qt.Popup)
self._editor.setFocusProxy(self)
self._editor.editingFinished.connect(self.handleEditingFinished)
self._editor.installEventFilter(self)
def eventFilter(self, widget, event):
if ((event.type() == QEvent.MouseButtonPress and not self._editor.geometry().contains(event.globalPos())) or (event.type() == QEvent.KeyPress and event.key() == Qt.Key_Escape)):
self._editor.hide()
return True
return QTabBar.eventFilter(self, widget, event)
def mouseDoubleClickEvent(self, event):
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())
class Window(QTabWidget):
def __init__(self):
QTabWidget.__init__(self)
self.setTabBar(EditableTabBar(self))
self.addTab(QWidget(self), 'Tab One')
self.addTab(QWidget(self), 'Tab Two')
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
PyQt6:
from PyQt6 import QtWidgets, QtGui, QtCore
class EditableTabBar(QtWidgets.QTabBar):
def __init__(self, parent=None):
super().__init__(parent)
self._lineedit = QtWidgets.QLineEdit(self)
self._lineedit.setWindowFlags(QtCore.Qt.WindowType.Popup)
self._lineedit.setFocusProxy(self)
self._lineedit.editingFinished.connect(self.edit_finished)
self._lineedit.installEventFilter(self)
def eventFilter(self, widget, event):
if event.type() == QtCore.QEvent.Type.MouseButtonPress:
if not self._lineedit.geometry().contains(event.globalPosition().toPoint()):
self.edit_finished()
self._lineedit.hide()
return True
elif event.type() == QtCore.QEvent.Type.KeyPress:
if event.key() == QtCore.Qt.Key.Key_Escape:
self._lineedit.hide()
return True
return super().eventFilter(widget, event)
def mouseDoubleClickEvent(self, event):
index = self.tabAt(event.pos())
if index >= 0:
self.editTab(index)
def editTab(self, index):
rect = self.tabRect(index)
self._lineedit.setFixedSize(rect.size())
self._lineedit.move(self.parent().mapToGlobal(rect.topLeft()))
self._lineedit.setText(self.tabText(index))
if not self._lineedit.isVisible():
self._lineedit.show()
def edit_finished(self):
index = self.currentIndex()
if index >= 0:
self._lineedit.hide()
self.setTabText(index, self._lineedit.text())
app = QtWidgets.QApplication([])
tabs = QtWidgets.QTabWidget()
tabs.setTabBar(EditableTabBar())
tabs.addTab(QtWidgets.QWidget(),'Tab 1')
tabs.addTab(QtWidgets.QWidget(),'Tab 2')
tabs.show()
app.exec()