Results 1 to 2 of 2
Hi,
I'm needing to write a very simple application and I'd like to do it in pygtk as a simple script, but I don't know how to get the Gnu/Gimp ...
- 06-07-2011 #1Just Joined!
- Join Date
- May 2009
- Location
- Oregon
- Posts
- 51
Python GTK digitization question.
Hi,
I'm needing to write a very simple application and I'd like to do it in pygtk as a simple script, but I don't know how to get the Gnu/Gimp toolkit to do something that happens in Gimp.
When doing a screen capture, Gimp enables a mode that allows the program to capture a Click or drag that is outside the graphical window to locate where the screen capture is going to happen.
I'd like to do the same thing, but I don't need screen capture capability -- just the ability to collect all clicks x,y positions (in pixels, or whatever units are convenient) from the mouse wherever they are, especially outside the graphics window I have for the python app -- and this needs to continue until I click on a release button to cancel the mode.
How can this be done from python? / where is documentation on this particular part of pyGtk ?
- 06-09-2011 #2Just Joined!
- Join Date
- May 2009
- Location
- Oregon
- Posts
- 51
Solved, but not well.
Well, I suppose the system update buried my question.
It took me two days to figure out -- yuck.
I took apart the source code for Gimp, only to find out they didn't use the GTK toolkit to do the screen capture. Highly disappointing....
I finally did find a poorly documented function called gtk.gdk.pointer_grab() that had made it possible to do.
It has one huge drawback, though, and that is a lack of any fine control over what does and does not get signals. Apparently one widget siezes control, and none of the other buttons, etc. get signals -- and nor does the rest of X11 except the root server. So, it tricky to work with. And although in theory, one ought to be able implement the signals by directly calling the objects and it "should" propagate to the parent (or siblings?) I couldn't get that to work.
Nor could I figure out a way to detect when the mouse entered the application area again to turn Off the capture using any simple signal or event; and even though mouse events can be routed to a callback function; there is an ugly in X11 with the mouse hints that causes all mouse data to stop flowing when the cursor leaves the window -- which generally leads to deadlock.
So, my solution, finally -- was to write it in two parts; I use a timer callback every half second to the mouse callback, and I force a read of the mouse position. That allows me to detect when the pointer leaves the application window -- and starts surfing the desktop;
If anyone knows a better way to do this -- I'd love to know, just to satisfy my curiosity. BTW, I'm not using global variables, but am passing a list of object references -- because it is easier than trying to figure which callback (switched, object, connect) works for which widget -- they seem to be quite inconsistent. In any event (chuckle) at least I didn't leave another TOTALLY unanswered question for people to find with Google....
Code:import gtk import gtk.gdk # the X11 interface is handled in gdk import gobject # needed for timer .... blah blah .... def hold( widgetsHold ): """ Callback from a toggle button to "hold" the pointers (screen grab). widgetsHold[0] is the list of all objects in the application widgetsHold[1] is the toggle buttion itself. To do a grab requires a gdk (not GTK window) element. The last three elements of the widget list is used to remember the state of the "hold" button and mouse pointer """ active=widgetsHold[1].get_active() widgetsHold[0][-1]= ( active and True ) widgetsHold[0][0].get_pointer() if widgetsHold[0][-2]: gdk.gtk.pointer_ungrab() widgetsHold[0][-2]=False return True def holdOn( widgets, event ): """ Track the mouse to determine when it leaves and enters the application window. None of the Enter, Focus, or other signals appear able to handle this when a grab is in effect. A timer calls this function periodically as well as the mouse but it only processes when the "hold" button is active wigets[-1] """ if not widgets[-1]: return True if event and event.is_hint: x=event.x; y=event.y else: x,y,state = widgets[0].window.get_pointer() xx,yy=widgets[0].get_size() now=True if (x>0 and y>0 and x<xx and y<yy): now=False if widgets[-2] == now: return True # already using correct setting # Toggle it whatever it is... if now: gtk.gdk.pointer_grab(widgets[0].get_window(), owner_events=False, event_mask=gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | 0, confine_to=None, cursor=gtk.gdk.Cursor( gtk.gdk.DOTBOX ) ) else: gtk.gdk.pointer_ungrab(); widgets[-2]=False widgets[-2]=now return True ... Blah Blah .... main() #...blah... #oh ... one mistake I made for time wasting, is I used a list rather than a named dictionary .... which was fast, but caused headaches remembering which number was which .... next time, I'd use a dictionary... widgets=[ window,[], False, [0,False,False,False, False, False ], [ [.5430e-9,[0,0]],[.5446e-9,[0,0]],[200,[0,0]],[1000,[0,0]],[False,[0,0]],[False,[0,0]], [0,(0,0)], 0, 0 ] ] ... # The button to start the grab fishing trip with... widget=gtk.ToggleButton("Hold") grab=widget widget.connect_object( "toggled", hold, [widgets, grab] ) # connect_object is needed to pass the widgets list; but # with toggle buttons it doesn't pass the "event" parameter # probably needs some other kind of callback -- but who knows # this definitely works, though. hbox.pack_start( widget, False, False, 0 ) widget.show() widgets[3][4]=widget ... widgets.extend( [ False,(False,False), False, False ] );# Track & warp window.connect_object("motion_notify_event", holdOn, widgets ) ... # blah... # and finally, the timer... gobject.timeout_add( 500, holdOn, widgets, False ); window.show() gtk.main()


Reply With Quote