单击 QTreeView 项目时防止 QComboboxView 自动折叠

Preventing QComboboxView from autocollapsing when clicking on QTreeView item

我正在使用 python3 + PyQt5。在我的程序中,我在该组合框中有 QCombobox 和 QTreeView。 QCOmbobox 默认行为是在单击项目时隐藏下拉列表。但是,在我的例子中,里面没有一个简单的列表,而是一个 TreeView。因此,当我在其中单击展开箭头时,QCombobox 会隐藏视图,因此我无法 select 一个项目

我这里没有任何具体代码,只是小部件初始化。我知道有信号和插槽,所以我的猜测是组合框捕获项目单击事件并将其包装在自己的行为中。所以我想我需要覆盖一些方法,但我不确定到底是哪个。

对于QComboBox中不想设置的项目,必须禁用项目的可选,例如:

import sys

from PyQt5 import QtWidgets, QtGui


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QComboBox()
    model = QtGui.QStandardItemModel()
    for i in range(3):
        parent = model
        for j in range(3):
            it = QtGui.QStandardItem("parent {}-{}".format(i, j))
            if j != 2:
                it.setSelectable(False)
            parent.appendRow(it)
            parent = it
    w.setModel(model)

    view = QtWidgets.QTreeView()
    w.setView(view)
    w.show()
    sys.exit(app.exec_())

一个更优雅的解决方案是覆盖模型的标志:

import sys

from PyQt5 import QtWidgets, QtGui, QtCore

class StandardItemModel(QtGui.QStandardItemModel):
    def flags(self, index):
        fl = QtGui.QStandardItemModel.flags(self, index)
        if self.hasChildren(index):
            fl &= ~QtCore.Qt.ItemIsSelectable
        return fl

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QComboBox()
    model = StandardItemModel()
    for i in range(3):
        parent = model
        for j in range(3):
            it = QtGui.QStandardItem("parent {}-{}".format(i, j))
            parent.appendRow(it)
            parent = it
    w.setModel(model)
    view = QtWidgets.QTreeView()
    w.setView(view)
    w.show()
    sys.exit(app.exec_())