[PyQt] How can I capture some mouse events but ignore others?
Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Thanks, Marc ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
It looks like you are not accepting the event, try: if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) event.accept() From the docs: void QEvent::accept () Sets the accept flag of the event object, the equivalent of calling setAccepted(true). Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget. See also ignore(). On 3/6/09 9:53 AM, Marc Nations mnations.li...@gmail.com wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Thanks, Marc ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
Thanks, wasn't aware of being able to accept events. So I tried this, instead of waiting for release I moved it up to when a button is pressed to get a better idea of what was happening. I tried this: def mousePressEvent(self, event): if event.button() == QtCore.Qt.RightButton: event.accept() self.rightClickMenu(event) else: event.ignore() According to the docs for the mouse events it should do this: You should call ignorehttp://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#ignore() if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accepthttp://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#accept(), or an event filter consumes it. My understanding of that is once I ignore the event it should automatically try the base class, which in this case is the base table widget. However using that code the left-click is basically disabled and nothing happens. So the event just seems to get dropped at that point. Is there something else I need to do to make the event retreat in the right direction? On Fri, Mar 6, 2009 at 9:19 AM, Brian Kelley kel...@eyesopen.com wrote: It looks like you are not accepting the event, try: if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) event.accept() From the docs: *void QEvent::accept () * Sets the accept flag of the event object, the equivalent of calling setAccepted(true). Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget. See also ignore(). - Show quoted text - On 3/6/09 9:53 AM, Marc Nations mnations.li...@gmail.com wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Thanks, Marc ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
Hmm, that is what I would have thought, you could always try calling the table widget directory in the case of ignores. Actually, I'll bet you have to do this since you have overridden the mousePressEvent function. QtGui.QTableWidget.mousePressEvent(event) On 3/6/09 10:47 AM, Marc Nations mnations.li...@gmail.com wrote: Thanks, wasn't aware of being able to accept events. So I tried this, instead of waiting for release I moved it up to when a button is pressed to get a better idea of what was happening. I tried this: def mousePressEvent(self, event): if event.button() == QtCore.Qt.RightButton: event.accept() self.rightClickMenu(event) else: event.ignore() According to the docs for the mouse events it should do this: You should call ignore http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#ignore () if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accept http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#accept (), or an event filter consumes it. My understanding of that is once I ignore the event it should automatically try the base class, which in this case is the base table widget. However using that code the left-click is basically disabled and nothing happens. So the event just seems to get dropped at that point. Is there something else I need to do to make the event retreat in the right direction? On Fri, Mar 6, 2009 at 9:19 AM, Brian Kelley kel...@eyesopen.com wrote: It looks like you are not accepting the event, try: if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) event.accept() From the docs: void QEvent::accept () Sets the accept flag of the event object, the equivalent of calling setAccepted(true). Setting the accept parameter indicates that the event receiver wants the event. Unwanted events might be propagated to the parent widget. See also ignore(). - Show quoted text - On 3/6/09 9:53 AM, Marc Nations mnations.li...@gmail.com http://mnations.li...@gmail.com wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Thanks, Marc ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
On Fri, 6 Mar 2009 07:50:57 -0800, Brian Kelley kel...@eyesopen.com wrote: Hmm, that is what I would have thought, you could always try calling the table widget directory in the case of ignores. Actually, I'll bet you have to do this since you have overridden the mousePressEvent function. QtGui.QTableWidget.mousePressEvent(event) On 3/6/09 10:47 AM, Marc Nations mnations.li...@gmail.com wrote: Thanks, wasn't aware of being able to accept events. So I tried this, instead of waiting for release I moved it up to when a button is pressed to get a better idea of what was happening. I tried this: def mousePressEvent(self, event): if event.button() == QtCore.Qt.RightButton: event.accept() self.rightClickMenu(event) else: event.ignore() According to the docs for the mouse events it should do this: You should call ignore http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#ignore () if the mouse event is not handled by your widget. A mouse event is propagated up the parent widget chain until a widget accepts it with accept http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qevent.html#accept (), or an event filter consumes it. My understanding of that is once I ignore the event it should automatically try the base class, which in this case is the base table widget. However using that code the left-click is basically disabled and nothing happens. So the event just seems to get dropped at that point. Is there something else I need to do to make the event retreat in the right direction? I think you are getting confused between the class hierarchy and the widget hierarchy. An ignored event is passed to the parent widget not the base class. Phil ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
On Friday 06 March 2009 06:53:01 am Marc Nations wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Look at QWidget.contextMenuEvent - it catches only right clicks. Overload that. If you want to grab those on the vertical or horizontal headers, I think you'll have to install an event filter on the respective QHeaderViews (QObject.installEventFilter) and grab only QContextMenuEvents for those objects. Jim ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
On 06.03.09 08:40:17, Jim Bublitz wrote: On Friday 06 March 2009 06:53:01 am Marc Nations wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Look at QWidget.contextMenuEvent - it catches only right clicks. Overload that. If you want to grab those on the vertical or horizontal headers, I think you'll have to install an event filter on the respective QHeaderViews (QObject.installEventFilter) and grab only QContextMenuEvents for those objects. The header views are qwidgets as well, so I don't see why that would be necessary. Apart from that, its even possible without overriding any base class, using QWidget.setContextMenuPolicy (set to Qt.CustomContextMenu) and catching the customContextMenuRequested() signal from the same widget. Or by using the Qt::ActionsContextMenu and adding a bunch of QActions to the table. Then you don't even need to take care of creating a menu. Andreas -- Good day to let down old friends who need help. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
On Friday 06 March 2009 09:06:03 am Andreas Pakulat wrote: On 06.03.09 08:40:17, Jim Bublitz wrote: On Friday 06 March 2009 06:53:01 am Marc Nations wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Look at QWidget.contextMenuEvent - it catches only right clicks. Overload that. If you want to grab those on the vertical or horizontal headers, I think you'll have to install an event filter on the respective QHeaderViews (QObject.installEventFilter) and grab only QContextMenuEvents for those objects. The header views are qwidgets as well, so I don't see why that would be necessary. Because you'd have to subclass them and replace the QTableWidget's original headers. It seems easier to install an event filter, but either method would work. Apart from that, its even possible without overriding any base class, using QWidget.setContextMenuPolicy (set to Qt.CustomContextMenu) and catching the customContextMenuRequested() signal from the same widget. That's probably easier than installing an event filter - wasn't aware of that. Jim Or by using the Qt::ActionsContextMenu and adding a bunch of QActions to the table. Then you don't even need to take care of creating a menu. Andreas ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt
Re: [PyQt] How can I capture some mouse events but ignore others?
On Fri, Mar 6, 2009 at 12:05 PM, Jim Bublitz jbubl...@nwinternet.comwrote: - Show quoted text - On Friday 06 March 2009 09:06:03 am Andreas Pakulat wrote: On 06.03.09 08:40:17, Jim Bublitz wrote: On Friday 06 March 2009 06:53:01 am Marc Nations wrote: Hi, I'm trying to create a custom table which pops up a menu when the user right clicks. This part works ok. It looks like this: class Table(QtGui.QTableWidget): def __init__(self, parent, gui): QtGui.QTableWidget.__init__(self, parent) self.gui = gui def mouseReleaseEvent(self, event): if event.button() == QtCore.Qt.RightButton: self.rightClickMenu(event) def rightClickMenu(self, event): pos = event.pos self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) The problem is that the default before of left click is changed, and I can't reset it. Without the mods the left clicks acts where if a multiple selection is made then clicking on another table cell de-selects all the previous items (unless a modifier key is used). With the above method, once multiple selections are made then it basically goes into shift mode and all previous selections are kept. I can't figure out a way to turn that off. Is there a way to cherry pick which mouse events you want and ignore the rest, basically letting them keep their default behavior? Because it looks like once the function is taken over then the default behaviors are lost. Look at QWidget.contextMenuEvent - it catches only right clicks. Overload that. If you want to grab those on the vertical or horizontal headers, I think you'll have to install an event filter on the respective QHeaderViews (QObject.installEventFilter) and grab only QContextMenuEvents for those objects. The header views are qwidgets as well, so I don't see why that would be necessary. Because you'd have to subclass them and replace the QTableWidget's original headers. It seems easier to install an event filter, but either method would work. Apart from that, its even possible without overriding any base class, using QWidget.setContextMenuPolicy (set to Qt.CustomContextMenu) and catching the customContextMenuRequested() signal from the same widget. That's probably easier than installing an event filter - wasn't aware of that. Jim Got it working. Here's the code for posterity: tableWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) QtCore.QObject.connect(tableWidget, QtCore.SIGNAL(customContextMenuRequested(QPoint)), self.contextMenu) def contextMenu(self, event): self.gui.ui.menuEdit.popup(QtGui.QCursor.pos()) Deceptively simple, but solves both problems. I don't have to sub-class the Table Widget, and I can simply borrow a menu I created with Qt Designer and not have to add it all in manually. Awesome. Thanks for all the help. ___ PyQt mailing listPyQt@riverbankcomputing.com http://www.riverbankcomputing.com/mailman/listinfo/pyqt