当QCheckBox信号改变时删除QHBoxLayout中的小部件

2024-03-28 16:53:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在QHBoxLayout中根据QCheckBox的信号变化显示/消失一些小部件。你知道吗

我读过一些文章(PyQt How to remove a layout from a layoutpyqt: how to remove a widget?)如何删除布局/小部件,但仍然没有设法修改代码以使其正常工作。你知道吗

在第一次单击之后,QHBoxLayouts中的新小部件会出现,但是在再次单击(取消选中按钮)之后,它就不工作了,而且这些小部件也不会消失。第三次点击它就会崩溃。你知道吗

下面是我的代码片段:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class CheckableComboBox(QComboBox):
    def __init__(self, parent = None):
        super(CheckableComboBox, self).__init__(parent)
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QStandardItemModel(self))

        self.setStyleSheet("QComboBox{"
                           "font-size:11px;"
                           "color:black;"
                           "background-color:white;"
                           "border:1px solid black;"
                           "padding:1px;""}")

        self.setEditable(True)
        self.lineEdit().setAlignment(Qt.AlignCenter)
        self.lineEdit().setReadOnly(True)
        self.setMinimumSize(200,40)

    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.text() != ' ' and item.checkState() == Qt.Checked:
            item.setCheckState(Qt.Unchecked)
        if item.text() != ' ' and item.checkState() != Qt.Checked:
            item.setCheckState(Qt.Checked)

class Main(QWidget):
    def __init__(self, parent = None):
        super(Main, self).__init__(parent)

        self.years = [' ', '2017', '2018', '2019', '2020']
        self.months = [' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
        self.metrics = [' ', 'Seller', 'Section', 'Store']
        self.units = [' ', 'Number of Pieces Sold', 'Total Value']

        self.setWindowTitle('Dialog')
        self.resize(360, 200)

        self.sMetric = QLabel('Select metric(s):')
        self.sUnit = QLabel('Select unit(s):')
        self.sYear = QLabel('Select year(s):')
        self.sMonth = QLabel('Select month(s):')

        self.timeWise = QCheckBox('Time-wise Overview')
        self.timeWise.stateChanged.connect(self.on_checked)

        self.okButton = QPushButton('Ok')
        self.cancelButton = QPushButton('Cancel')

        self.metricCombo = CheckableComboBox()
        for index, element in enumerate(self.metrics):
            self.metricCombo.addItem(element)
            if index > 0:
                item = self.metricCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.unitCombo = CheckableComboBox()
        for index, element in enumerate(self.units):
            self.unitCombo.addItem(element)
            if index > 0:
                item = self.unitCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.monthCombo = CheckableComboBox()
        for index, element in enumerate(self.months):
            self.monthCombo.addItem(element)
            if index > 0:
                item = self.monthCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.yearCombo = CheckableComboBox()
        for index, element in enumerate(self.years):
            self.yearCombo.addItem(element)
            if index > 0:
                item = self.yearCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.firstR = QHBoxLayout()
        self.firstR.addWidget(self.sMetric)
        self.firstR.addWidget(self.metricCombo)

        self.secondR = QHBoxLayout()
        self.secondR.addWidget(self.sUnit)
        self.secondR.addWidget(self.unitCombo)

        self.thirdR = QHBoxLayout()
        self.thirdR.addWidget(self.timeWise)

        self.fourthR = QHBoxLayout()
        self.fourthR.addWidget(self.sYear)
        self.fourthR.addWidget(self.yearCombo)

        self.fifthR = QHBoxLayout()
        self.fifthR.addWidget(self.sMonth)
        self.fifthR.addWidget(self.monthCombo)

        self.mainV = QVBoxLayout()
        self.mainV.addLayout(self.firstR)
        self.mainV.addLayout(self.secondR)
        self.mainV.addLayout(self.thirdR)

        self.setLayout(self.mainV)

    def on_checked(self, state):
        if state == Qt.Checked:
            print('Checked')
            self.mainV.addLayout(self.fourthR)
            self.mainV.addLayout(self.fifthR)
        else:
            print('Unchecked')
##            self.mainV.removeWidget(self.sMonth)
##            self.mainV.removeWidget(self.monthCombo)
##            self.mainV.removeWidget(self.sYear)
##            self.mainV.removeWidget(self.yearCombo)

            self.fourthR.deleteLater()
            self.fifthR.deleteLater()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    main = Main()
    main.show()
    sys.exit(app.exec_())

有什么建议吗?你知道吗


Tags: selfindexmodelifelementitemqtchecked
1条回答
网友
1楼 · 发布于 2024-03-28 16:53:38

我改用QGridLayout,现在它可以按我的要求工作了,结果如下:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class CheckableComboBox(QComboBox):
    def __init__(self, parent = None):
        super(CheckableComboBox, self).__init__(parent)
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QStandardItemModel(self))

        self.setStyleSheet("QComboBox{"
                           "font-size:11px;"
                           "color:black;"
                           "background-color:white;"
                           "border:1px solid black;"
                           "padding:1px;""}")

        self.setEditable(True)
        self.lineEdit().setAlignment(Qt.AlignCenter)
        self.lineEdit().setReadOnly(True)
        self.setMinimumSize(150, 40)

    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.text() != ' ' and item.checkState() == Qt.Checked:
            item.setCheckState(Qt.Unchecked)
        if item.text() != ' ' and item.checkState() != Qt.Checked:
            item.setCheckState(Qt.Checked)

class Example(QWidget):

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

        self.init_UI()

    def init_UI(self):
        self.years = [' ', '2017', '2018', '2019', '2020']
        self.months = [' ', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
        self.metrics = [' ', 'Seller', 'Section', 'Store']
        self.units = [' ', 'Number of Pieces Sold', 'Total Value']

        self.setWindowTitle('Dialog')

        self.sMetric = QLabel('Select metric(s):')
        self.sUnit = QLabel('Select unit(s):')
        self.okButton = QPushButton('Ok')
        self.cancelButton = QPushButton('Cancel')

        for i in (self.sMetric, self.sUnit, self.okButton, self.cancelButton):
            i.setFixedHeight(40)
            i.setFixedWidth(150)

        self.timeWise = QCheckBox('Time-wise View')
        self.timeWise.stateChanged.connect(self.on_checked)

        self.metricCombo = CheckableComboBox()
        for index, element in enumerate(self.metrics):
            self.metricCombo.addItem(element)
            if index > 0:
                item = self.metricCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.unitCombo = CheckableComboBox()
        for index, element in enumerate(self.units):
            self.unitCombo.addItem(element)
            if index > 0:
                item = self.unitCombo.model().item(index, 0)
                item.setCheckState(Qt.Unchecked)

        self.grid = QGridLayout()
        self.grid.setSpacing(10)

        self.grid.addWidget(self.sMetric, 1, 0)
        self.grid.addWidget(self.metricCombo, 1, 1)
        self.grid.addWidget(self.sUnit, 2, 0)
        self.grid.addWidget(self.unitCombo, 2, 1)
        self.grid.addWidget(self.timeWise, 3, 0)
        self.grid.addWidget(self.okButton, 6, 0)
        self.grid.addWidget(self.cancelButton, 6, 1)

        self.setLayout(self.grid)

    def on_checked(self, state):
        if state == Qt.Checked:
            print('Checked')

            self.sYear = QLabel('Select year(s):')
            self.sMonth = QLabel('Select month(s):')

            for i in (self.sYear, self.sMonth):
                i.setFixedHeight(40)
                i.setFixedWidth(150)

            self.monthCombo = CheckableComboBox()
            for index, element in enumerate(self.months):
                self.monthCombo.addItem(element)
                if index > 0:
                    item = self.monthCombo.model().item(index, 0)
                    item.setCheckState(Qt.Unchecked)

            self.yearCombo = CheckableComboBox()
            for index, element in enumerate(self.years):
                self.yearCombo.addItem(element)
                if index > 0:
                    item = self.yearCombo.model().item(index, 0)
                    item.setCheckState(Qt.Unchecked)

            self.grid.addWidget(self.sYear, 4, 0)
            self.grid.addWidget(self.yearCombo, 4, 1)
            self.grid.addWidget(self.sMonth, 5, 0)
            self.grid.addWidget(self.monthCombo, 5, 1)

        else:
            print('Unchecked')
            self.sYear.deleteLater()
            self.sMonth.deleteLater()
            self.monthCombo.deleteLater()
            self.yearCombo.deleteLater()

if __name__ == '__main__':

    app = QApplication(sys.argv)
    main = Example()
    main.show()
    sys.exit(app.exec_())

相关问题 更多 >