views:

820

answers:

2

I've got a QComboBox with a custom list object.

Please see Screen shot

The custom list object has a custom mousePressEvent so that when the user click on one of the circles with a +/- (a twisty), the list is expanded/collapsed.

When I use the list with the combo box, when the user clicks on a twisty, the list is expanded/collapsed, but the selection is changed, and the list is hidden. How can I filter this so that when the user click on a twisty, the selection is not changed, and the list not hidden.

A: 

Off the top of my head, you could subclass QComboBox and override hideEvent(QHideEvent) (inherited from QWidget)

def hideEvent(self, event):
  if self.OkToHide():
    event.accept()
  else:
    event.ignore()

Your screenshot looks like an interesting use of a combo box, I'm curious as to why you haven't used a TreeView style control instead of a list?

Edit (Mar 14 2009):

I looked at the Qt source code and it looks like when the keyboard and mouse events are captured, that as soon as qt has decided to emit the "activated(int index)" signal, "hidePopup()" has been called.

So apart from rewriting their event filter code, another option is to connect the "activated(int index)" or "highlighted(int index)" signal to a slot that can call "showPopup()" which would re-raise the list items. If you get a nasty disappear/appear paint issue you may have to get Qt to delay the paint events while the popup is visible.

Hope that helps!

Chris Cameron
Just for perfect clarity, you would have to implement self.OkToHide() obviously :)
Chris Cameron
I tried that on the combo box. hideEvent only gets called when the window is close. I added the following hideEvent to the list. It gets called - but does not prevent hiding.def hideEvent(self, event): event.ignore()
Gary van der Merwe
> Why not a TreeView?Well - I am using a TreeView control - but I've reimplemented the expanding and collapsing of nodes - because the data that I am displaying is a DAG and not a tree - to the requirement are a bit different. See for an example of a DAG:http://garyvdm.googlepages.com/qlog.png
Gary van der Merwe
See updated edit, I hope it helps resolve your issue.
Chris Cameron
A: 

QT has a eventFilter that "captures" QEvent.MouseButtonRelease. So what I have done is installed my own eventFilter that filters QEvent.MouseButtonRelease events if the user click on a node.

In my list object I have the following method:

def mousePressEvent (self, e):
    self.colapse_expand_click = False
    if <user clicked node>:
        colapse_expand_node()
        e.accept ()
        self.colapse_expand_click = True

The mousePressEvent runs before mouseReleaseEvent.

Then in the custom combobox, I filter the event:

class RevisionSelectorWidget(QtGui.QComboBox):
    def __init__(self, parent = None):
        QtGui.QComboBox.__init__(self, parent)

        self.log_list = RevisionSelectorLogList(self)
        self.setView(self.log_list)
        self.log_list.installEventFilter(self)
        self.log_list.viewport().installEventFilter(self)

    def eventFilter(self, object, event):
        if event.type() == QtCore.QEvent.MouseButtonRelease:
            if self.log_list.colapse_expand_click:
                return True
        return False
Gary van der Merwe