PyQt:如何在选择项目时保持ComboBox打开

时间:2022-01-28 23:01:50

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

遵循以下链接提供的解决方案(效果很好):

PyQt: How to set Combobox Items be Checkable?

PyQt:如何设置Combobox项目是否可检查?

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

如何在选择项目时保持ComboBox打开?目前,通过提供的解决方案,在每个选择上,列表折叠...

2 个解决方案

#1


1  

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.

以下是保持列表打开的链接解决方案的修订版。可以通过单击其外部或按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_())

#2


1  

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).

也许最好使用QListWidget / QListView。如果您使用每个QListWidgetItem或在自定义模型中设置它们(例如使用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!").

我建议不要使用组合框的原因:该小部件不打算保持打开以进行多项选择;你会违反用户的期望并且应该会遇到可用性问题(“如何关闭这些选择?它不像其他人那样工作!”)。

#1


1  

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.

以下是保持列表打开的链接解决方案的修订版。可以通过单击其外部或按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_())

#2


1  

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).

也许最好使用QListWidget / QListView。如果您使用每个QListWidgetItem或在自定义模型中设置它们(例如使用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!").

我建议不要使用组合框的原因:该小部件不打算保持打开以进行多项选择;你会违反用户的期望并且应该会遇到可用性问题(“如何关闭这些选择?它不像其他人那样工作!”)。