【问题标题】:QTabWidget not letting me use custom classQTabWidget 不允许我使用自定义类
【发布时间】:2020-10-30 09:56:33
【问题描述】:

编辑:措辞并包括一个最小可重复的例子

我有一个关于对象名称在 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_())

【问题讨论】:

标签: python oop pyqt pyqt5 qt-designer


【解决方案1】:

我不明白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_())

【讨论】:

  • 这正是我想要的!明天我会仔细查看代码,但从运行它并尝试功能我可以看到它正在做我正在尝试做的事情。谢谢! (编辑:我不能投票,因为我还没有 15 个代表,但我很感激!)
  • @WhoDatBoy 你检查答案了吗?您可以获得 2rep 并给响应者 15 rep。请点击✓按钮。
  • @Haru 刚刚点击了检查按钮
猜你喜欢
  • 2019-05-01
  • 1970-01-01
  • 2015-12-13
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
相关资源
最近更新 更多