Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt: How to keep ComboBox open while selecting items

Following the solution provided at the following link (which works nicely):

PyQt: How to set Combobox Items be Checkable?

How can I keep ComboBox open while selecting items? Currently, with the offered solution, on each select, the list collapses...

like image 820
E. Liberman Avatar asked Sep 03 '25 13:09

E. Liberman


2 Answers

Below is a revision of the linked solution that keeps the list open. The list can be closed by clicking outside of it, or by pressing Esc.

from PyQt4 import QtCore, QtGui

class CheckableComboBox(QtGui.QComboBox):
    def __init__(self, parent=None):
        super(CheckableComboBox, self).__init__(parent)
        self.view().pressed.connect(self.handleItemPressed)
        self._changed = False

    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.checkState() == QtCore.Qt.Checked:
            item.setCheckState(QtCore.Qt.Unchecked)
        else:
            item.setCheckState(QtCore.Qt.Checked)
        self._changed = True

    def hidePopup(self):
        if not self._changed:
            super(CheckableComboBox, self).hidePopup()
        self._changed = False

    def itemChecked(self, index):
        item = self.model().item(index, self.modelColumn())
        return item.checkState() == QtCore.Qt.Checked

    def setItemChecked(self, index, checked=True):
        item = self.model().item(index, self.modelColumn())
        if checked:
            item.setCheckState(QtCore.Qt.Checked)
        else:
            item.setCheckState(QtCore.Qt.Unchecked)

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.combo = CheckableComboBox(self)
        for index in range(6):
            self.combo.addItem('Item %d' % index)
            self.combo.setItemChecked(index, False)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.combo)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 200, 100)
    window.show()
    sys.exit(app.exec_())
like image 59
ekhumoro Avatar answered Sep 05 '25 13:09

ekhumoro


Perhaps better use a QListWidget/QListView instead. The checkable flags should work with that, too, if you set them with each QListWidgetItem or in your custom model (e. g. using a QStandardItemModel).

Reason why I advise against using a combo box: That widget isn't meant to stay open for multiple selection; you would violate user expectations and should expect usability problems ("How can I close that selection? It doesn't work like the others!").

like image 39
Murphy Avatar answered Sep 05 '25 11:09

Murphy