1

I'm using python3 + PyQt5. In my program I have QCombobox and a QTreeView inside that combobox. The QCOmbobox default behavior is to hide the dropdown list when an item is clicked. However, in my case there is not a simple list inside it, but a TreeView. So when I'm clicking an Expand Arrow in it, QCombobox hides the view so I can not select an item enter image description here

I have no any specific code here, just widget initialization. I know that there are signals and slots so my guess here is that combobox catches the item click event and wraps it in its own behavior. So I think I need to override some method but I'm not sure which exactly.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Sergey Maslov
  • 758
  • 1
  • 8
  • 22
  • According to the image you show, you only want the popup to close if you click on the item child2, or rather those items that do not have children. I am right? – eyllanesc Apr 25 '18 at 10:31
  • @eyllanesc that's right. but the popup closes automatically even if I click just arrow – Sergey Maslov Apr 25 '18 at 10:32

1 Answers1

1

You must disable the item being selectable to the items that you do not want to be set in the QComboBox, for example:

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_())

A more elegant solution is to overwrite the flags of the model:

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • your solution is great, but it does not allow to choose parent items. I want to be able to choose parent items, my problem is that when I click an arrow to expand a parent it gets selected – Sergey Maslov Apr 25 '18 at 12:28
  • @SergeyMaslov You have to be clear, so I ask you the question and point out that if you wanted the items that do not have children are only selectable and you said yes. – eyllanesc Apr 25 '18 at 12:30
  • I'm sorry for this misunderstanding. I got your question wrong – Sergey Maslov Apr 25 '18 at 12:32
  • @SergeyMaslov you should indicate that it is not selectable only when the arrow is pressed. – eyllanesc Apr 25 '18 at 12:34
  • yes. I need to be able to select both parent and child but not when I click the arrow. And the tricky thing here is to override arrow clicking method – Sergey Maslov Apr 25 '18 at 12:36