I'm using a QDialog with transparency enabled to select a region of the screen for a screen capture tool. When the user clicks inside the transparent widget I want to ignore the mouse event so that the system handles it. Is this possible?
I'm trying to achieve this on Linux.
Some things I have tried with no success:
QtWidgets.QWidget.setWindowFlags(QtCore.Qt.WindowTransparentForInput)
QtWidgets.QWidget.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
QtWidgets.QWidget.setMask(QtGui.QRegion(self.geometry()))
Subclassing mousePressEvent and ignoring the event
You have to use the flag X11BypassWindowManagerHint so that you omit the window manager next to WindowTransparentForInput so that the system knows that it only has to show the window but does not notify you about the inputs.
w.setWindowFlags(w.windowFlags() |
QtCore.Qt.WindowTransparentForInput |
QtCore.Qt.X11BypassWindowManagerHint)
Related
I have a QMainWindow application that generates multiple QWidget popups. I would like to know how I can destroy the pop up QWidgets if the user clicks on the main QMainWindow. I am not sure how to proceed with the resolution of this problem. I do not want to interfere with any QMainWindow events, I just want to destroy the additional pop up windows by any mouse click outside of the pop up widgets area. Is it possible or recommended via signal slot mechanism or eventFilter? Is it possible without dealing with (x,y) coordinates?
Thanks for the suggestions.
I managed to solve my problem. I implemented a custom label (like this) that contains a mousePressedEvent. On clicking this label a Pop widget is generated. The mousePressEvent is not propagated any further from the label. Then I implemented a mousePressedEvent in the QMainWindow where I check for existence of popup windows. If they exist, I close them all. Note that If I do not stop mouse propagation in the label mousePressEvent, on clicking the label the pop window is generated but it is immediately closed by the QMainWindow mousePressEvent because (most likely) the event is propagating to QMainWindow. At least, that solves my problem.
Thanks
I have a subclass of QGraphicsItem and I want to track mouse position every time I hover the mouse on that Item alone and it should give the relative position to the QGraphicsItem. I know, how to handle this when there is QWidget (using QWidget.setMouseTracking) and QMainWindow (by installing event filters), but I cant figure out how to do it for QGraphicsItem. The mouse move event is only triggered, when there is mouse press event, but that's not what is want. I want a trigger whenever I hover on that QGraphicsItem. Please provide your suggestions
You will want to use my_item.setAcceptHoverEvents(True) to enable mouse move events without the mouse press event.
Note, this will not trigger a mouseMoveEvent but will instead trigger a hoverMoveEvent (along with hoverEnterEvent and hoverLeaveEvent when you initially move the mouse over or off the QGraphicsItem respectively. So make sure you override this method in your subclass of QGraphicsItem.
I'm using win32api in a Python script to control mouse movements. It's working fantastic, but as soon as I click (I also generate click events) outside my Python shell/IDE, all my mouse events immediately stop. If I click my shell/IDE again, control is restored.
It seems like mouse control is only working when my Python shell or IDE is the "active" window - is there any way to retain mouse control even after Python is sent to the background?
Turns out this was not a Python issue, but was an issue with the device I was using to generate mouse movements. A separate API call was required to allow this device to push events when its owner was out of focus.
A part of a small project I am working on involves 'calibrating' the coordinates of the screen of which to take a screen capture of.
By the 'screen', I refer to the entire desktop, not my GUI window.
The coordinates are calibrated when a QDialog window appears (which I've subclassed).
The user is prompted to click several locations on the screen.
I need the program to record the locations of all mouse clicks occuring anywhere on the screen - ones that don't natively trigger a QDialog mouseEvent, since they are outside this window.
Obviously overwriting the mouseEvent method does not work, since the QDialog doesn't recieve the clicks.
How can I capture global mouse clicks, so that an event is triggered and sent to the QDialog when any part of the screen is clicked?
(I'd prefer a Qt based solution, but am open to other libraries if need be).
Thanks!
There are some cross-platform examples of how to do this with http://pypi.python.org/pypi/autopy/0.51
I've assumed this isn't possible and am instead using pyHook,
letting Qt pump the messages.
I have a Qt program with many buttons, user-interactable widgets, etc.
At one stage in the program, I would like all the widgets to temporarily 'stop working'; stop behaving to mouse clicks and instead pass the event on to one function.
(This is so the User can select a widget to perform meta operations. Part explanation here: Get variable name of Qt Widget (for use in Stylesheet)? )
The User would pick a widget (to do stuff with) by clicking it, and of course clicking a button must not cause the button's bound function to run.
What is the correct (most abstracted, sensible) method of doing this?
(which doesn't involve too much new code. ie; not subclassing every widget)
Is there anything in Qt designed for this?
So far, I am able to retrieve a list of all the widgets in the program (by calling
QObject.findChildren(QtGui.QWidget)
so the solution can incorporate this.
My current horrible ideas are;
Some how dealing with all the applications events all the time in one
function and not letting through the events when I need the
application to be dormant.
When I need dormancy, make a new transparent widget which recieves
mouse clicks and stretch it over the entire window. Take coordinates
of click and figure out the widget underneath.
Somehow create a new 'shell' instance of the window.
THANKS!
(Sorry for the terrible write-up; in a slight rush)
python 2.7.2
PyQt4
Windows 7
You can intercept events send to specific widgets with QObject::installEventFilter.
graphite answered this one first so give credit where credit is due.
For an actual example in PySide, here's an example you might draw some useful code from:
my_app.py
from KeyPressEater import KeyPressEater
if __name__ == "__main__":
app = QApplication(sys.argv)
eater = KeyPressEater()
app.installEventFilter(eater)
KeyPressEater.py
class KeyPressEater(QObject):
# subclassing for eventFilter
def eventFilter(self, obj, event):
if self.ignore_input:
# swallow events
pass
else:
# bubble events
return QObject.eventFilter(self,obj,event)