Using PyQT, how do you filter mousePressEvent for a QComboBox with custom list
Question
I've got a QComboBox
with a custom list object.
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.
Additional screenshots
All of the nodes collapsed:
List hidden:
Solution
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
OTHER TIPS
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!