Question: It seems that ButtonPress events on tkinter give the location of the click w/r to the top left corner of the window. However, when you click on a Button widget, a ButtonPress event occurs, but the x,y location values given are w/r to the top left corner of the Button. How can I get the ButtonPress event to occur at the location w/r to the top left corner of the window, not the button?
Details: I have a tkinter program that lets users draw on a picture (layout below), but only occurs below a certain y value. If you move the cursor below that threshold (aka below the picture and into an area that has instructions), no drawing functionality can occur. Drawing only occurs with clicks, so <Button-1> is bound to a class method that keeps track of where the click occurred and draws on the picture at that location:
self.root.bind('<Button-1>', self.addDot)
However, in the area that has instructions, there is an undo button. Clicking on it in theory should undo the last click's effect. Instead, if I click on it, it registers a <ButtonPress> event that has x and y values with respect to the top left corner of the button, not the window. I do not know how to differentiate when the x,y location of a button press occurs w/r to the window or the button, so the self.addDot function executes near the top left of the image. Everywhere else you click behaves as normal.
One caveat I have seen is that if I change the binding to be on the canvas, not the root, this strangely goes away and behaves as expected. Why is that?
Layout:
Related
What I want to achieve:
I want to detect the situation when the user is dragging a file over the Kivy app window.
What I already know:
I know how to detect hovering mouse coursor over widgets (with on_mouse_pos), I also know how to detect if a file is dropped onto the window (with on_file_drop).
So, is it possible to see whether the cursor is hovering over the window and "holding" a file? Because then I want to display some prompt (eg. 'Drop HERE'). I hope you get the idea :)
I'm not really sure, because there's this thing with SDL2 (and probably even with old pygame) when the Window just pauses (try some animation or something) when you e.g. drag it with the window decoration (the thing where title and _ O X are). That is the behavior if you do something with the Window directly.
Although, the Window looks like it behaves normally (doesn't pause itself), when you drag file on top of it (I tried with examples/animation/animate.py), to do such thing you'd need to do either the hovering behavior + handling the collisions or bind to mouse_pos.
However, when binding to mouse_pos, it seems like the Window still isn't capable of handling the input from outside and at the same time get mouse properties correctly (I think it's similar to the behavior when you click & drag outside of the Window and Button remains pressed, but this is kind of inversed).
edited animate.py:
class TestApp(App):
def on_mouse_pos(self, win, args):
print args
...
def build(self):
...
from kivy.core.window import Window
Window.bind(mouse_pos=self.on_mouse_pos)
return button
Therefore if you can't get even mouse position when a mouse button is being held, I don't think such an action is possible. You can however make the areas where you want to drop the file already different (e.g. change background) when you'll expect a user to drop the file - a very dirty workaround from UI side for such a problem.
Side note: Kivy should be able to get most (if not all) SDL2 window events via Cython, therefore if you find such event in SDL2 that would make fetching mouse position possible, such action could be performed, feel free to make a feature request in kivy/kivy or make a pull request.
I would like to create GUI on my RPi so that I can scroll through Listbox like I do in my iPhone, without the use of a scrollbar. In other words, by just touching the listbox and 'flicking' your finger up/down, I would like to be able to scroll.
Can this scrolling method be done with TKinter or any GUI for RPi?
Yes it is.
Just have a look how the binding of scrollbars work.
How can you achieve the desired effect? Bin Mouse-Move events (touch move is nothing else) and use it to connect it to yview / xview depending on what scroll you want to have.
(e.g. check the direction your mouse moves inside your callback and use that information to trigger the scrolling event.)
If further help is needed, let us know.
Edit:
Here some "dummy-code"...
# this is your callback bound to mouse-move event
def mouse_move_callback(event):
# use event.y with a previous remembered y value to determine
# directions
directions = 1 # just as an example, could also be -1
# scroll the listbox vertically.
# to increase scrolling speed, either multiply counter by some value >1
# or replace 'units' which means scroll 1 character in the current setting
# by 'pages' for larger steps. 'pages' should scroll the visible
# area of the listbox further.
listbox.yview_scroll(1, 'units')
You could also use mouse button press and mouse button release to trigger the actions. Mouse button press would then store an y value (beginn of scroll) and mouse button release would be bound to the above callback.
I am having trouble setting a default button for a gtk table in a window.
It is a 4x3 table, and I want to set the center button to be the default.
I have the center button set as default, but it is not behaving correctly when I move it with the arrow keys.
Please check out my code at: http://dpaste.com/3M36W8X
The center button is set as default button at line 118 At lines 189 and 190, if I switch "self.window.show()" with "self.table.show()" the buttons behave correctly, but I can't default a button.
The way it is set now, the center button is set as default initially, but as soon as I move with the arrow keys, it acts as though there wasn't a default key to begin with.
Please let me know if I can describe this problem better!
I have a program somewhat similar to Microsoft Paint, and I'm working on implementing canvas resizing. I need to detect if the mouse cursor has moved into resizing range, and if the left mouse button is held down while the mouse is being moved. I have a QGraphicsRectItem set up as my canvas, and I want to detect mouse movement and mouse button state in my QGraphicsRectItem, without it being selected.
I've been using QGraphicsItem.hoverMoveEvent for detecting if the cursor is within resizing range or not, but when the left mouse button is held down, hoverMoveEvent is no longer triggered.
There's mouseMoveEvent, but as the docs say:
If you do receive this event, you can be certain that this item also
received a mouse press event, and that this item is the current mouse
grabber.
In my program, it's impractical for my canvas to be the current mouse grabber when resizing. I may have other objects that need to retain their selection states while the canvas is being resized.
I realize I could do this in the QGraphicsScene containing my QGraphicsRectitem, but to avoid interdependence between them, I'd like to be able to do this all in my QGraphicsRectItem.
So my question is: How, if possible, do I detect mouse movement and mouse button states on a QGraphicsRectitem without the it being selected?
I'm developing an application that contains a number of panes. See the screenshot:
The left settings pane is a wx.ScrolledPanel that contains a number of wx.Panels.
The top events pane is a wx.grid.Grid.
The bottom data pane is a wx.Panel that contains a wx.grid.Grid.
The middle plot pane is a wx.Panel containing an enthought chaco plot.
The right detector pane is a wx.Panel.
I would like to implement focus follows mouse so that when I move my mouse over the plot I can immediately zoom in or out using my scroll wheel without first clicking on the plot to give it the focus.
Similarly when I move my mouse over the left settings , the top events or the bottom data panes I would like to be able to immediately scroll the window using the scroll wheel without first clicking on the window.
Currently I defined a function:
def focusFollowsMouse(window):
window.Bind(wx.EVT_ENTER_WINDOW, lambda event: window.SetFocus())
I would like to apply this function only on the four top-level panes: plot, settings, events and data.
However I need to call this function for each sub-panel or control in each of the top-level panes to get this to work. For example I need to apply this function individually to the Measurement Settings, Analysis Parameters, View Settings etc. panels.
Most likely the EVT_ENTER_WINDOW event is not propagated to parent windows.
Is there a way to get this to work without applying focusFollowsMouse to each and every sub-panel or control?
Thanks
This is Windows' behaviour - it works as you expect under GTK. Personally, I'd leave your app as it is, for consistency with other Windows applications, and install WizMouse