GTK StatusIcon: Coordinates of left-click? - python

how do I get the x/y-coordinates of a left click in a Gtk StatusIcon?
This is my first GTK app and I'm stuck. Is there any way to get details about the last button event that occurred? Or is it possible to pass those details to the handler function when connect()ing the "activate" callback?
Greets,
Philip

Since the status icon isn't a widget, it's a bit roundabout. You might be able to pass in some kind of widget as part of the user parameter object and get the global mouse position on activate. See here on how you might.

Related

How to set focus to the old window on button click in PyQt5 Python?

My Current Project is to create a On Screen Keyboard for my personal usage with my personal functionality. I made gui and primary function in PyQt5 with Python. I managed to type the letter on button click with pyautogui.write() method. But the problem is, where I want to type there is no focus. suppose I want to write on chrome's address bar or any other input field on my monitor. when I click on button to type a letter, chrome lost focus. I want to set focus to the old window while press on any button. I searched on google about this but didn't found any answer. How can i set focus to old window? or is there any better way to type on focus lost state?
You should not try to "set the focus back", as it would be almost impossible to know what window had the focus before (and a new window might raise in the meantime). What you should actually do is to prevent your window to get focus at all, thus avoiding it to steal focus from the others.
In order to achieve this, you must set the appropriate window flag (or initialize the widget with it using the flags keyword argument), which for this is Qt.WindowDoesNotAcceptFocus.
Note that you might also want to set the Qt.WindowStaysOnTopHint in order to always keep your window above the others:
class MyKeyboard(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(
QtCore.Qt.WindowDoesNotAcceptFocus
| QtCore.Qt.WindowStaysOnTopHint
)

Python/PySide: How to make a widget that will stay on top of the main window, but not cover up other widgets?

So I have a script running inside another program (The Foundry's Hiero) and I'm just making a new QWidget object, and calling self.show()
Now, I can set it to self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint), so my window will stay on top of the main window, even if you click on something in the main window.
The problem is, this is a sort of popup window that you configure settings in, and it triggers other QWidget popups. If I set my window to WindowStaysOnTopHint, those subdialogs that my widget triggers end up beneath my widget.
Is there a way in PySide/PyQt to make a window stay on top/keep focus from the main application window in particular, but not everything?
You can use the QApplication.focusChanged signal to raise your widget up when Hiero's main window is selected. Then you would just need to remove the WindowStaysOnTopHint flag.
I'm not familiar with Hiero's API, but I'm guessing you could try something like:
def raiseMyWidget(old, new):
if new == hiero.ui.mainWindow():
myWidget.raise_()
QtWidgets.QApplication.instance().focusChanged.connect(raiseMyWidget)
Hope this helps! You can take advantage of the old parameter or some other means to make sure that your widget isn't raised above the others as well.

Adding a tooltip to an image

I'm trying to add a tooltip to an image. Following a PyGTK tutorial it seems that this should work:
image = gtk.Image()
image.set_from_file(image_path)
box.pack_start(image, expand=False)
tooltip = gtk.Tooltips()
tooltip.set_tip(image, "Hello!")
Except it doesn't. Nothing happens when I mouse over the image. However, I know that works with buttons (I ran the sample code from the tutorial).
With GTK 2.12 and above, I could probably just use image.set_tooltip_text("Hello!") but I'm stuck at 2.10.4 and have to use gtk.Tooltips.
Edit
According to the documentation for gtk.Tooltips:
Tooltips can only be set on widgets which have their own X window. To check if a widget has its own window use widget.flags()&gtk.NO_WINDOW. To add a tooltip to a widget that doesn't have its own window, place the widget inside a gtk.EventBox and add a tooltip to the eventbox instead.
So that solves my problem but leaves me a bit confused. I checked the flags for a button and it has the same gtk.NO_WINDOW flag that images have. So why don't buttons need an EventBox but images do?
To satisfy its interface, GktButton creates an event box (well, something like an event box) for itself, internally. I.e. it captures events in a non-visible gdk window. GtkImage doesn't have a similar interface to satisfy so it doesn't need to capture events.
Perhaps it's an accident of the button's internal implementation that using the tooltip interface works without embedding a button in an EventBox or perhaps the tooltip interface actually depends upon a gdk window whether it's visible or not and the Widget interface lacks that sort of flag.

How to get clicks on disabled buttons with wxpython?

I have a disabled button, and it does not receive clicks when I use EVT_BUTTON on it. Is there a way to receive clicks even when it has been Disabled()?
The whole point of disabling a button is so that the EVT_BUTTON event is not fired. I'm sure you could create create an ugly hack using EVT_LEFT_DOWN and detecting where the mouse is in your app as a workaround, but why bother? This is intended behavior.
Perhaps wxpython has a mechanism similar to pygtk.
In pygtk you create a input-only (that is transparent) window over the widget you want to get clicks for and get your clicks there.

How to specify a full click in Python Tkinter

The following python line will bind the method "click" to the event when the user presses the mouse button while the pointer is on the widget; no matter where the pointer is when she releases the button.
self.bind('<Button-1>',self.click)
If I use "ButtonRelease" instead of "Button" in the code, it seems that the method "click" will be called for the widget on which the mouse was pressed after the button release; no matter where you release it.
1- Isn't there a neat way to make it call the bound method only if the mouse button was released on my widget; no matter where it was pressed?
2- Isn't there neat way to tell it to react only in case of a full click (press and release both on the same widget)?
1- Isn't there a neat way to make it
call the bound method only if the
mouse button was released on my
widget; no matter where it was
pressed?
2- Isn't there neat way to tell it to
react only in case of a full click
(press and release both on the same
widget)?
No "neat" way, because, as Tkinter's docs say:
When you press down a mouse button
over a widget, Tkinter will
automatically "grab" the mouse
pointer, and mouse events will then be
sent to the current widget as long as
the mouse button is held down.
and both of your desires are incompatible with this automatic grabbing of the mouse pointer on press-down (which I don't know how to disable -- I think it may be impossible to disable, but proving a negative is hard;-).
So, you need more work, and a non-"neat" solution: on the button-down event's callback, bind the enter and leave events (to bound methods of a class instance where you can track whether the mouse is currently inside or inside the widget of interest) of that window as well as the button-release; this way, when the release event comes, you know whether to perform the "actual application callback" (if inside) or do nothing (if outside) -- that gives you your desire number 2, but describing this as neat would be a stretch.
Desire number 1 is even harder, because you have to track enter and leave events on EVERY widget of interest -- it's not enough to know one bit, whether the mouse is inside or outside, but rather you must keep track of which widget (if any) it's currently in, to direct the "actual application callback" properly (if at all) at button release time.
While the internals aren't going to be neat, each functionality can be bound into one neat-to-call function... with slightly "indaginous" internals (a term that's used more often to refer to root canal work or the like, rather than programming, but may be appropriate when you're wanting to go against the grain of functionality hard-coded in a framework... that's the downside of frameworks -- you're in clover as long as you want to behave in ways they support, but when you want to defeat their usual behaviors to do something completely different, that can hardly ever be "neat"!-).
The tkinter documentation does provide you info on that:
http://www.pythonware.com/library/tkinter/introduction/events-and-bindings.htm
You can do a binding on
<ButtonRelease-1>
Binding on ButtonRelease-1 isn't enough. The callback won't fire until the button is released, but it doesn't matter where the mouse is when it's released. What governs is where the mouse was when it was clicked, as Alex Martelli's said. An easy way to get the desired behavior is to put everything on a canvas, and bind the callback to ButtonRelease-1. Now you have something like
def callback(event):
x1, y1, x2, y2 = canvas.bbox(widget)
if x1 <= event.x <= x2 and y1 <= event.y <= y2:
<whatever>
I've used this approach in my own code to get arbitrary widgets to behave like buttons in this respect.

Categories