我创建了一个添加新选项卡的功能,其中只有新选项卡有关闭按钮,我的意思是,"Tab 1"而"+"没有关闭按钮。所以这是代码:
"Tab 1"
"+"
tabs.py from PyQt5 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") MainWindow.resize(628, 504) self.centralwidget = QtWidgets.QWidget(MainWindow) self.centralwidget.setObjectName("centralwidget") self.tabWidget = QtWidgets.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(36, 34, 541, 396)) self.tabWidget.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor)) self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded) self.tabWidget.setTabsClosable(False) self.tabWidget.setObjectName("tabWidget") self.tab1 = QtWidgets.QWidget() self.tab1.setObjectName("tab1") self.tabWidget.addTab(self.tab1, "") self.tab2 = QtWidgets.QWidget() self.tab2.setObjectName("tab2") self.tabWidget.addTab(self.tab2, "") MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 628, 21)) self.menubar.setObjectName("menubar") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab1), _translate("MainWindow", "Tab 1")) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab2), _translate("MainWindow", "+")) main.py from tabs import Ui_MainWindow from PyQt5 import QtCore, QtGui, QtWidgets class Tab(QtWidgets.QMainWindow, Ui_MainWindow): tabs_list = [] def __init__(self): super().__init__() self.setupUi(self) self.tabWidget.tabBarClicked.connect(self.newTab) self.tabs_list.append(self.tab1) self.tabs_list.append(self.tab2) def newTab(self, event): if event == len(self.tabs_list) - 1: tab = QtWidgets.QWidget() self.tabWidget.addTab(tab, "+") self.tabs_list.append(tab) self.tabWidget.setTabText(len(self.tabs_list) - 2, "Tab " + str(len(self.tabs_list) - 1)) self.setClosableTabs() def setClosableTabs(self): self.tabWidget.setTabsClosable(False) self.tabWidget.setTabsClosable(True) self.tabWidget.tabBar().setTabButton(0, QtWidgets.QTabBar.RightSide, None) self.tabWidget.tabBar().setTabButton(len(self.tabs_list) - 1, QtWidgets.QTabBar.RightSide, None) self.tabWidget.tabCloseRequested.connect(self.closeTab) def closeTab(self, event): print("close tab: ", event) self.tabWidget.removeTab(event)
当我尝试添加关闭功能时,我遇到了包含要关闭的选项卡索引的事件,该事件触发的次数与选项卡数量相同,因此它会关闭多个选项卡。我做错了什么?
tabCloseRequested每次设置可关闭的标签时,您都会连接信号。每次将信号连接到插槽时,信号发出时将调用插槽:如果您连接两次,则插槽将被调用两次。
tabCloseRequested
在您的情况下,如果您创建了两个选项卡,则关闭信号将被连接两次,因此如果您尝试关闭第一个选项卡,closeTab(0)则会被调用两次,从而导致关闭第一个和第二个选项卡(在前一个选项卡被删除后,第二个选项卡将成为第一个)。
closeTab(0)
从中删除连接setClosableTabs并将其放入__init__:
setClosableTabs
__init__
class Tab(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): # ... self.tabWidget.tabCloseRequested.connect(self.closeTab)
请注意,您的实现也存在其他问题,其中最重要的是使用选项卡小部件的内部列表。
Qt 已经提供了您所需要的:count()返回选项卡数量,并widget(index)根据索引返回单个小部件,以防您需要它。 通常不鼓励使用任何其他方法,因为如果未正确实现,可能会导致错误或意外行为,而这正是您的情况:
count()
widget(index)
newTab()
想象一下如果您创建同一个 Tab 类的两个实例会发生什么:如果您向第一个窗口添加一个选项卡,那么第二个窗口也会在其 中看到该选项卡tabs_list,因为它是所有实例之间共享的类属性。
tabs_list
这是您要尝试执行的操作的一个更好且实际上更简单的实现(请注意,您应该从 UI 中删除第二个“+”选项卡,因为它是通过编程添加的):
class Tab(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.tabWidget.tabBarClicked.connect(self.newTab) self.tabWidget.setTabsClosable(True) self.tabWidget.tabCloseRequested.connect(self.closeTab) # add the "+" tab to the tabbar, not the tabwidget lastTab = self.tabWidget.tabBar().addTab('+') self.tabWidget.tabBar().setTabButton(lastTab, QtWidgets.QTabBar.RightSide, None) def newTab(self, event): if event == self.tabWidget.count() - 1: tab = QtWidgets.QWidget() tabName = "Tab {}".format(self.tabWidget.count()) self.tabWidget.insertTab(self.tabWidget.count() - 1, tab, tabName)