Python pyqt5:一些小部件在我的标签中消失了

Python pyqt5:一些小部件在我的标签中消失了,python,pyqt,pyqt5,Python,Pyqt,Pyqt5,我正在实现我的自我标签,但是一些小部件消失了 我的代码是: from PyQt5.QtWidgets import * import sys class TypeManagerLabel(QLabel): def __init__(self): super().__init__() layout = QVBoxLayout() self.setLayout(layout) btnLayout = QHBoxL

我正在实现我的自我标签,但是一些小部件消失了

我的代码是:



from PyQt5.QtWidgets import *
import sys


class TypeManagerLabel(QLabel):


    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        btnLayout = QHBoxLayout()
        self.__nameLineEdit = QLineEdit()
        self.__opBtn = QPushButton('Add/Remove')
        self.__colorBtn = QPushButton('Color')
        btnLayout.addWidget(self.__nameLineEdit)
        btnLayout.addWidget(self.__opBtn)
        layout.addLayout(btnLayout)


class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        # layout.addStretch()
        lab2 = QPushButton('test')
        layout.addWidget(lab2)

app = QApplication(sys.argv)
dialog = MyWin()
dialog.show()
app.exec_()
目前,标签正常,结果应为:

现在,我希望QLineEdit应该位于标签的顶部,因此我添加了一个拉伸。代码是:

class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        layout.addStretch()  ###################### add the stretch
        lab2 = QPushButton('test')
        layout.addWidget(lab2)


from PyQt5.QtWidgets import *
import sys


class TypeManagerLabel(QWidget):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        btnLayout = QHBoxLayout()
        self.__nameLineEdit = QLineEdit()
        self.__opBtn = QPushButton('Add')
        btnLayout.addWidget(self.__nameLineEdit)
        btnLayout.addWidget(self.__opBtn)

        layout.addLayout(btnLayout)

        infoLabel = QLabel()
        layout.addWidget(infoLabel)

        self.__infoLayout = QVBoxLayout()
        infoLabel.setLayout(self.__infoLayout)

        self.__opBtn.clicked.connect(self.addRemoveSlot)


    def addRemoveSlot(self, checked=False):

        name = self.__nameLineEdit.text()
        layout = QHBoxLayout()
        checkBox = QCheckBox()
        lineEdit = QLineEdit(name)
        layout.addWidget(checkBox)
        layout.addWidget(lineEdit)
        self.__infoLayout.addLayout(layout)


class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        # layout.addStretch()
        lab2 = QPushButton('test')
        layout.addWidget(lab2)

app = QApplication(sys.argv)
dialog = MyWin()
dialog.show()
app.exec_()

结果是:

在上图中,QLineEdit消失了

@

我的环境是:

win 10
python 3.7.8
pyqt5 5.14.0

--------------------------------更新----------------------------------

感谢MusicCamante和Heike的建议,它们是QWidget的子类,而不是QLabel。但是在我添加了一些新的小部件之后,新的bug被报告了。代码是:

class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        layout.addStretch()  ###################### add the stretch
        lab2 = QPushButton('test')
        layout.addWidget(lab2)


from PyQt5.QtWidgets import *
import sys


class TypeManagerLabel(QWidget):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        btnLayout = QHBoxLayout()
        self.__nameLineEdit = QLineEdit()
        self.__opBtn = QPushButton('Add')
        btnLayout.addWidget(self.__nameLineEdit)
        btnLayout.addWidget(self.__opBtn)

        layout.addLayout(btnLayout)

        infoLabel = QLabel()
        layout.addWidget(infoLabel)

        self.__infoLayout = QVBoxLayout()
        infoLabel.setLayout(self.__infoLayout)

        self.__opBtn.clicked.connect(self.addRemoveSlot)


    def addRemoveSlot(self, checked=False):

        name = self.__nameLineEdit.text()
        layout = QHBoxLayout()
        checkBox = QCheckBox()
        lineEdit = QLineEdit(name)
        layout.addWidget(checkBox)
        layout.addWidget(lineEdit)
        self.__infoLayout.addLayout(layout)


class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        # layout.addStretch()
        lab2 = QPushButton('test')
        layout.addWidget(lab2)

app = QApplication(sys.argv)
dialog = MyWin()
dialog.show()
app.exec_()

当我在QLineEdit中输入字符串并单击“添加”按钮时,结果是:

上面的数字是我所期望的

但如果我在代码中添加拉伸:

class MyWin(QLabel):

    def __init__(self):
        super().__init__()

        layout = QVBoxLayout()
        self.setLayout(layout)

        lab1 = TypeManagerLabel()
        layout.addWidget(lab1)
        layout.addStretch() ###################### add the stretch
        lab2 = QPushButton('test')
        layout.addWidget(lab2)

然后,如果我在QLineEdit中输入一个字符串并单击“添加”按钮,预期的小部件将不会出现。

QLabel是一种非常特殊的小部件。虽然它看起来很简单,但事实并非如此:它在处理大小时有自己的行为,这是为了满足所有需求,一个主要基于(可能)可变文本大小的小部件,不仅在水平方向上,而且在垂直方向上

也就是说,永远不要尝试将布局和子小部件添加到不打算用作容器的类中,最重要的是,不应该在具有特殊行为的小部件(如QLabel)上进行添加。
使用这样一个小部件来包含其他小部件不仅是一个非常糟糕的想法,而且完全没有用,因为您实际上没有使用QLabel提供的真正功能(显示文本或图像)

要添加子级和布局,只需使用嵌套布局、普通QWidget类或任何其他容器小部件,如QGroupBox或QFrame

即使在注释之后,您仍在尝试向QLabel添加小部件。移除该标签,只需将布局添加到主布局

class TypeManagerLabel(QWidget):
    def __init__(self):
        super().__init__()
        # ...

        layout.addLayout(btnLayout)

        self.__infoLayout = QVBoxLayout()
        layout.addLayout(self.__infoLayout)

        self.__opBtn.clicked.connect(self.addRemoveSlot)

    # ...
类类型管理器标签(QWidget):
定义初始化(自):
super()。\uuuu init\uuuuu()
# ...
布局。添加布局(btnLayout)
self.\uuu infoLayout=QVBoxLayout()
layout.addLayout(self.\u infoLayout)
self.\u opBtn.clicked.connect(self.addRemoveSlot)
# ...

通常不鼓励在现有的Qt类中添加子窗口小部件和布局,而对QLabel这样的特殊窗口小部件(它有自己的大小管理“规则”)这样做是个坏主意。既然没有使用QLabel的任何特性,为什么要将这些小部件添加到QLabel中?因为我会在几个类中使用这些小部件组。因此,我想在QLabel中收集这些小部件。这个自我实现是一个模块,我可以在任何地方使用它。如果自实现QLabel不是一个好的解决方案。如何对这些小部件进行分组?只需将QWidget子类化,而不是QLabel。QWidget是一个通用小部件,几乎所有其他小部件都是从它派生出来的。有几种方法可以做到这一点,使用嵌套布局通常是最常见的(您已经在
TypeManagerLabel
中这样做了,只需在主布局中添加“分组”即可如果要保持更结构化的方法,则从QWIDGET中添加子类,并将QLabor添加到其布局中。也考虑到存在一些特定类,它们作为容器使用:QGulpBox,QFrice是最简单和常用的,但是您也有更多的“页面”。基于QTabWidget或QStackedWidget之类的小部件。@Heike感谢您的建议。现在,我使用QWidget而不是QLabel。但是,如果我想添加新的小部件,仍然会报告错误。我已经更新了解释。最后,我用QWidget安装了所有QLabel。非常感谢。不客气。请记住,如果答案解决了您的问题,您应该uld通过单击其左侧的复选符号将其标记为已接受。