1

As part of a larger project, I am trying to create a snapshot tool that works similar to the Mac OS X snapshot. It should take a first click, a second click, and return an image of the area created by the square.

I have some python functions that take an first point (x, y) and a second point (x, y) and create a snapshot of the square that those points create on the screenshot. The missing piece is getting the mouse locations of the initial click and second click, then passing that data to the python program to create the snapshot.

In other words, the flow of the program should be:

  1. first click (save x, y)
  2. second click (save x2, y2)
  3. run snapshot.py using the saved clicked data to return the screenshot

I've only found solutions that can return the position of the pointer within a frame. If it helps, I'm using "import gtk" and "from Xlib import display"

edit: I have tried to use Tkinter to make an invisible frame that covers the whole screen. The idea was to use that invisible frame to get the exact coordinates of two mouse clicks, and then the invisible frame would disappear, pass the coordinates on to the screenshot function, and it would be done. However, the code I've been writing doesn't keep the frame transparent.

edit 2: This code can create a window, make it transparent, size it to the screen, then return the mouse coordinates on that window. I can use this to simply return the mouse coordinates on two clicks, then remove the window and send those coordinates to the snapshot code. When I run the below code line-by-line in the python shell, it works perfectly. However, whenever I run the code as a whole, it seems to skip the part where it makes the window transparent. Even if I copy and paste a block of code that includes the 'attributes("-alpha", 0.1)' into the python shell, it ignores that line.

from Tkinter import *

root = Tk()
root.attributes('-alpha', 0.1)

maxW = root.winfo_screenwidth()
maxH = root.winfo_screenheight()

root.geometry("{0}x{1}+0+0".format(maxW, maxH))

def callback(event):
    print "clicked at: ", event.x, "and: ", event.y

root.bind("<Button-1>", callback)

def Exit(event):
    root.destroy()
root.bind("<Escape>", Exit)


# root.overrideredirect(True)

root.mainloop()

I am open to using any c or c++ code, or any language's code, to return the coordinates of the mouse on a click. This guy wrote some code to actually make the computer click at given points, which may be on the same track as my problem.

cbsm1th
  • 230
  • 4
  • 12
  • I'm not familiar with gtk, but as a general principle, how about spawning a transparent frame that is the same size as the screen whenever you need to take a snapshot? [This person says their code](http://stackoverflow.com/a/4902541/1460057) accomplishes the transparent window part, and if you have the mouse position code, you should be all set. – Brionius Aug 13 '13 at 02:38
  • Thanks,that pointed me in the right direction but I'm still having problems – cbsm1th Aug 13 '13 at 13:47
  • Cool! The transparent frame is awesome - I'm going to use that for something sometime. I found the problem with the callback - see answer below. – Brionius Aug 13 '13 at 13:50

1 Answers1

1

It's just a indentation problem - you bound the callback in the callback by mistake - try this instead:

root.geometry("{0}x{1}+0+0".format(maxW, maxH))

def callback(event):
    print "clicked at: ", event.x, "and: ", event.y

root.bind("<Button-1>", callback)

EDIT

Ok, here's a theory - maybe when you run it from the command line, it takes longer for the root window to appear, for some reason, so you set the alpha before it exists, and the alpha option gets ignored. Give this a try:

root.wait_visibility(root)
root.attributes('-alpha', 0.1)
Brionius
  • 13,858
  • 3
  • 38
  • 49
  • That actually was an error in copying the code into stackoverflow... the real problem lies somewhere else. When I run the code line by line in the Python shell, the window pops up, it fills the screen, it gets transparent, and it returns the "clicked at x, y" text fine. But when I run the code with "python file.py", it brings up a completely different scenario. The frame that pops up is filled in white and NOT transparent, and doesn't return the mouse position any more. Any thoughts? – cbsm1th Aug 13 '13 at 13:56
  • @swagadactyl Oh, huh - I can't reproduce that in Mac OS X 10.7 and python 2.7 - it works fine for me both running from the command line and in a python shell. I'd guess it has something to do with the system you're using. What OS are you using? Also, what python shell are you using, and is it the same python that you get with the command `which python`? – Brionius Aug 13 '13 at 13:58
  • Ubuntu. It seems odd that there is a difference between the program run line-by-line in the shell, and the program run all at once with 'python file.py'. Is this supposed to happen? – cbsm1th Aug 13 '13 at 14:00
  • 'which python' returns /usr/bin/python, 'python --version' returns Python 2.7.3, and 'python', which runs the shell, shows its running Python 2.7.2 [GCC 4.6.3] on linux2 – cbsm1th Aug 13 '13 at 14:01
  • Hmm...do you know why there is a discrepancy between `python --version` and the version that the python shell reports? My suspicion is that the windowing manager that is invoked when you run it in the shell supports compositing, and a different windowing manager is invoked when you run it from the command line. The solution I would try to find would be to make sure when I type `python file.py` I'm using the exact same python install as the python shell, since it worked in the shell. – Brionius Aug 13 '13 at 14:10
  • Once again that was a typing error... the shell returns Python 2.7.3 as well. I have updated the problem in the question body! – cbsm1th Aug 13 '13 at 14:13
  • @swagadactyl: Added another possible solution - fingers crossed. – Brionius Aug 13 '13 at 14:28
  • Thank you! This worked! I suspected that the 'idle' time between running each line in the python shell had something to do with it. – cbsm1th Aug 13 '13 at 14:40