I am trying to show/disappear some widgets in QHBoxLayout dependently on signal changes from QCheckBox.
I have read some articles (PyQt How to remove a layout from a layout; pyqt: how to remove a widget?) how to remove the layouts/widgets but still have not managed to amend the code so that it worked correctly.
After first click the new widgets in QHBoxLayouts appear but after another click (unchecking the button) it simply does not work and these do not disappear. At third click it crashes.
Here below is a snippet of my code:
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_())
Any suggestions how to proceed?