如何从多选QComboBox获取已检查项目? - python

我能够使用QComboBox和QStandardItemModel实现多选,但是我无法使用selectedItems()或checkedItems()选项来获取所选项目,该选项给出的错误消息显示为:

AttributeError: 'QComboBox' object has no attribute 'selectedItems'               
AttributeError: 'QComboBox' object has no attribute 'checkedItems'

有没有一种方法可以获取QComboBox的选定项目列表?
下面是我的代码的示例实现

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

    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)

class Dialog_01(QMainWindow):
    def __init__(self):
        super(QMainWindow,self).__init__()       
        years = ["2017", "2018", "2019", "2020"]
        self.comboBoxv = QComboBox(self)
        self.model = QtGui.QStandardItemModel(self)
        firstItem = QtGui.QStandardItem("Select  Years")
        firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
        firstItem.setSelectable(False)
        self.model.setItem(0, 0, firstItem)
        for i,area in enumerate(years):
            item = QtGui.QStandardItem(area)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setData(Qt.Unchecked, Qt.CheckStateRole)
            self.model.setItem(i+1, 0, item)
        self.comboBoxv.setModel(self.model)        
        self.comboBoxv.installEventFilter(self)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

参考方案

CheckedItems方法不存在,因此会出现该错误。解决方案是遍历模型并验证是否已检查。

from PyQt5 import QtCore, QtGui, QtWidgets

class CheckableComboBox(QtWidgets.QComboBox):
    closedPopup = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(CheckableComboBox, self).__init__(parent)
        self.setView(QtWidgets.QListView(self))
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QtGui.QStandardItemModel(self))

        firstItem = QtGui.QStandardItem("Select  Years")
        firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
        firstItem.setSelectable(False)
        self.model().appendRow(firstItem)

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    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)

    def checkedItems(self):
        l = []
        for i in range(self.model().rowCount()):
            it = self.model().item(i)
            if it.checkState() == QtCore.Qt.Checked:
                l.append(it.text())
        return l

    def hidePopup(self):
        self.closedPopup.emit()
        super(CheckableComboBox, self).hidePopup()
        QtCore.QTimer.singleShot(0, lambda: self.setCurrentIndex(0))

class Dialog_01(QtWidgets.QMainWindow):
    def __init__(self):
        super(Dialog_01,self).__init__()       
        years = ["2017", "2018", "2019", "2020"]
        self.comboBoxv = CheckableComboBox()
        self.comboBoxv.closedPopup.connect(self.on_closedPopup)
        for i, area in enumerate(years):
            item = QtGui.QStandardItem(area)
            item.setCheckable(True)
            item.setCheckState(QtCore.Qt.Unchecked)
            self.comboBoxv.model().appendRow(item)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(self.comboBoxv)
        lay.addStretch()

    @QtCore.pyqtSlot()
    def on_closedPopup(self):
        print(self.comboBoxv.checkedItems())

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    dialog_1 = Dialog_01()
    dialog_1.show()
    dialog_1.resize(480,320)
    sys.exit(app.exec_())

Python sqlite3数据库已锁定 - python

我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…

Python:在不更改段落顺序的情况下在文件的每个段落中反向单词? - python

我想通过反转text_in.txt文件中的单词来生成text_out.txt文件,如下所示:text_in.txt具有两段,如下所示:Hello world, I am Here. I am eighteen years old. text_out.txt应该是这样的:Here. am I world, Hello old. years eighteen a…

用大写字母拆分字符串,但忽略AAA Python Regex - python

我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…

如何在PyQt4的动态复选框列表中检查stateChanged - python

所以我要从PyQt4的列表中添加复选框。但是我找不到在Window类中对每个状态使用stateChanged的方法。这是从列表元素添加它们的功能: def addCheckbox(self): colunas = Graphic(self.caminho).getColunas() for col in colunas: c = QtGui.QCheckBo…

如何每隔n秒运行一个函数,但又不中断其他代码?也许在后台运行? - python

Python是我的第一语言,因此如果没有意义,请理解我。我正在用python制作虚拟宠物。我将Tkinter用于GUI。我想每5秒在Action类中运行一次display方法。但是,如果我使用线程,时间表或时间并将代码放在按钮的正前方,它就会冻结并只运行显示方法。如何在不中断按钮和其他部件的情况下每5秒运行一次显示方法?class Pet: def __in…