【问题标题】:How to show widgets created in another QWidget Class?如何显示在另一个 QWidget 类中创建的小部件?
【发布时间】:2021-05-13 18:12:30
【问题描述】:

我尝试使用 PyQt5 创建一个用户界面,用户可以在其中创建和删除标签,每个标签都是在文本输入 (QLineEdit) 之后创建的按钮 (QPushButton),并且每个标签按钮都伴随着一个相关的 X-按钮,点击时删除标签。

为此,我创建了第一个 QWidget 类来创建和显示主要的小部件(输入框、添加标签按钮和整体布局)。

然后我创建了第二个 QWidget 类来生成每个标签按钮及其关联的 X 按钮。当用户单击第一个 QWidget 类的“添加标签”按钮时,会生成此类元素。

我的问题是我现在找不到如何正确显示此类生成的标签和 X 按钮。当我点击添加标签按钮时什么都没有出现,而生成标签和 X 按钮的函数被正确调用(我检查了打印)。

GUI 无法显示标签和 X 按钮:

代码如下:

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLineEdit, QWidget, QVBoxLayout, QHBoxLayout, QGridLayout, QGroupBox
import sys


class MyWindow(QMainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.setWindowTitle("My Program")
        self.setGeometry(100, 100, 1500, 1500)
        self.initUI()

    def initUI(self):
        widgets = MainWidgets()
        self.setCentralWidget(widgets)


class MainWidgets(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.grid = QGridLayout()
        self.grid.setColumnStretch(0, 1)
        self.grid.setColumnStretch(1, 1)
        self.grid.setColumnStretch(2, 1)
        self.grid.setColumnStretch(3, 1)

        self.labelEntry = QLineEdit(self)

        self.addLabelButton = QPushButton(self)
        self.addLabelButton.setText("Add Label")
        self.addLabelButton.clicked.connect(self.addNewLabel)

        self.hbox_labelAdd = QVBoxLayout()
        self.hbox_labelAdd.addWidget(self.labelEntry)
        self.hbox_labelAdd.addWidget(self.addLabelButton)

        self.vbox1 = QVBoxLayout()
        self.vbox1.addLayout(self.hbox_labelAdd)

        self.vbox2 = QVBoxLayout()
        self.vbox2.addStretch(1)

        self.vbox_right = QVBoxLayout()
        self.vbox_right.addLayout(self.vbox1)
        self.vbox_right.addLayout(self.vbox2)

        self.groupBox = QGroupBox("Labelling")
        self.groupBox.setLayout(self.vbox_right)

        self.grid.addWidget(self.groupBox, 0, 3)
        self.setLayout(self.grid)

    def addNewLabel(self):
        labelname = self.labelEntry.text()
        newLabelItems = Labels(self, labelname)
        self.vbox1.addWidget(newLabelItems)


class Labels(QWidget):
    def __init__(self, parent, labelname, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.mylabelname = labelname
        self.initUI()

    def initUI(self):
        self.labelButton = QPushButton(self)
        self.labelButton.setText(str(self.mylabelname))
        self.labelButton.clicked.connect(self.printbutton)
        self.buttonErase = QPushButton(self)
        self.buttonErase.setText("X")
        self.buttonErase.clicked.connect(self.erasebutton)

    def printbutton(self):
        print('clicked:', self.labelButton.text())

    def erasebutton(self):
        self.labelButton.deleteLater()
        self.buttonErase.deleteLater()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # app.setStyle('Fusion')
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

我通过创建一个空的 QPushButton 并将其与布局中的标签和 X 按钮相关联找到了一个技巧,这允许显示标签和 X 按钮,但这不是一个长期的解决方案,而且我不能找到一种在布局中全宽显示这些标签和 X 按钮的方法,由于某种我无法解释的原因,限制为一半的布局(无论我使用网格、Vbox 还是 Hbox 布局)。

这里是技巧代码(替换之前代码中的def addNewLabel(self)函数):

    def addNewLabel(self):
        labelname = self.labelEntry.text()
        newLabelItems = Labels(self, labelname)
        fake_widget = QPushButton(self)
        labelitems_lay = QHBoxLayout()
        labelitems_lay.addWidget(fake_widget)
        labelitems_lay.addWidget(newLabelItems)
        self.vbox1.addLayout(labelitems_lay)

在下图中,您可以看到使用此技巧的效果: 具有技巧的 GUI - 放大感兴趣的区域:

总体目标是能够以与此图非常相似的方式生成按钮: 表示所需输出的方案:

我认为我遇到的问题与布局有关,因为昨天感谢@furas,我能够实现这个目标,但使用 move() 函数来显示按钮。现在我正在尝试使用布局来组织我的 UI,很遗憾我无法再实现它了。

【问题讨论】:

    标签: python pyqt pyqt5 qpushbutton


    【解决方案1】:

    一种方法是将两个按钮添加到Labels.initUi 中的布局中,例如

    
    class Labels(QWidget):
        ....
    
        def initUI(self):
            self.labelButton = QPushButton(self)
            self.labelButton.setText(str(self.mylabelname))
            self.labelButton.clicked.connect(self.printbutton)
            self.buttonErase = QPushButton(self)
            self.buttonErase.setText("X")
            self.buttonErase.clicked.connect(self.erasebutton)
    
            layout = QHBoxLayout(self)
            layout.setContentsMargins(0,0,0,0)
            layout.addWidget(self.labelButton, stretch=1)
            layout.addWidget(self.buttonErase, stretch=0)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-06
      • 2019-11-19
      • 2019-02-19
      • 2014-11-03
      • 2020-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多