编辑:短语并包括一个最小的可复制示例
我有一个关于对象名称在PyQt5中如何工作/ OOP在PyQt5中如何工作的问题:
我正在开发一个包含QTabWidget的项目。每次单击“ +”选项卡时,此QTabWidget都会添加一个新选项卡:
点击之前:
点击后:
当我使用insertNewRegionTab()
将新标签页添加为空白小部件时,一切正常。但是,当我改用QtWidgets.QWidget(customTab)的派生类自定义类时,程序崩溃。我创建了此类,以便每个选项卡在对象之间具有相同的格式/内部关系,并且可以使用“ +”按钮添加任意数量的内容。
我认为崩溃可能是由于名称冲突引起的,例如同时在两个标签中创建一个名为“ label1”的标签。
问题是,如果每个customTab是它自己的对象,我看不出名称冲突怎么可能成为问题。我想知道是否有人知道为什么我不能以期望的方式实现这个customTab类。
我对解决方案的想法是只定义类计数器,然后在每次添加新选项卡时都递增,因此它们都有唯一的名称,但这有点麻烦,所以我想确保这实际上是问题是在实现之前。
-使用此代码的两个原始标签将没有名称。左侧的“测试1”中有一个组合框,位于customTab类中。右侧的“ +”添加了一个新标签,但是添加了一个普通的QWidget而不是customTab对象
from PyQt5 import QtCore, QtGui, QtWidgets
class topLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
# Function that is used to add tabs
def insertNewRegionTab(self):
if self.mainTabWidgetCount == 1 + self.mainTabWidget.currentIndex():
# Attempted method 1:
tab = QtWidgets.QWidget() # Want this to be a customTab not a QWidget
self.mainTabWidget.insertTab(self.mainTabWidget.currentIndex(),
tab, "Tab " + str(self.mainTabWidgetCount))
# Attempted method 2:
# self.tabInstaces.append(customTab(self.mainTabWidget))
self.mainTabWidgetCount += 1
super().__init__()
# Initialization of main window
self.setObjectName("MainWindow")
self.resize(500, 300)
self.centralwidget = QtWidgets.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_5 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_5.setObjectName("gridLayout_5")
# Create the main tab widget and set properties
self.mainTabWidget = QtWidgets.QTabWidget(self.centralwidget)
self.mainTabWidget.setObjectName("mainTabWidget")
self.mainTabWidget.setCurrentIndex(0)
self.gridLayout_5.addWidget(self.mainTabWidget, 1, 1, 1, 1)
self.setCentralWidget(self.centralwidget)
# Insert a tab (of the custom, pre-formatted tab class) into this tab widget
self.tabInstances = [customTab(self.mainTabWidget)]
self.mainTabWidgetCount = 2
# Add the tab which creates other tabs to the tan widget
self.addRegionTab = QtWidgets.QWidget()
self.addRegionTab.setObjectName("addRegionTab")
self.mainTabWidget.addTab(self.addRegionTab, "")
# Add functionality: When '+' tab is selected, add a tab
self.mainTabWidget.currentChanged.connect(lambda: insertNewRegionTab(self))
# Show window
self.show()
class customTab(QtWidgets.QWidget):
def __init__(self, parent=None):
# Initializes the object itself and renames it. Add vertical layout to it
super(customTab, self).__init__()
self.setObjectName("tabInstances")
self.verticalLayout = QtWidgets.QVBoxLayout(self)
self.verticalLayout.setObjectName("verticalLayout")
self.comboBox1 = QtWidgets.QComboBox(self)
self.comboBox1.setObjectName("comboBox1")
self.comboBox1.addItem("")
self.comboBox1.addItem("")
# Add self to parent
parent.addTab(self, "")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = topLevelWindow()
sys.exit(app.exec_())
答案 0 :(得分:2)
我不了解OP的逻辑,因为它询问与该问题无关的objectName(),objectName仅是一个允许我们识别元素的名称,而没有其他内容。
在我的回答中,我展示了如何创建在按下时必须添加标签的按钮:
from PyQt5 import QtCore, QtGui, QtWidgets
class TabWidget(QtWidgets.QTabWidget):
plusClicked = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.tabBar().installEventFilter(self)
self.add_button = QtWidgets.QToolButton(self, text="+")
self.add_button.clicked.connect(self.plusClicked)
def eventFilter(self, obj, event):
if obj is self.tabBar() and event.type() == QtCore.QEvent.Resize:
r = self.tabBar().geometry()
h = r.height()
self.add_button.setFixedSize((h - 1) * QtCore.QSize(1, 1))
self.add_button.move(r.right(), 0)
return super().eventFilter(obj, event)
class topLevelWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# Initialization of main window
self.setObjectName("MainWindow")
self.resize(500, 300)
self.centralwidget = QtWidgets.QWidget(self)
self.setCentralWidget(self.centralwidget)
lay = QtWidgets.QGridLayout(self.centralwidget)
# Create the main tab widget and set properties
self.mainTabWidget = TabWidget()
self.mainTabWidget.setObjectName("mainTabWidget")
self.mainTabWidget.setCurrentIndex(0)
lay.addWidget(self.mainTabWidget, 1, 1, 1, 1)
self.mainTabWidget.addTab(CustomWidget(), "Tab1")
self.mainTabWidget.plusClicked.connect(self.add_clicked)
def add_clicked(self):
index = self.mainTabWidget.count() + 1
self.mainTabWidget.addTab(CustomWidget(), "Tab {}".format(index))
class CustomWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
# Initializes the object itself and renames it. Add vertical layout to it
super(CustomWidget, self).__init__(parent)
self.comboBox1 = QtWidgets.QComboBox()
self.comboBox1.addItems(list("abcdef"))
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.comboBox1)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = topLevelWindow()
w.show()
sys.exit(app.exec_())