0

GUI noob here. I've created a simple screen overlay where the user can click-drag to create a transparent rectangle.

Think 'cropping an image'.

That part was easy enough. The problem is that I want to reset the overlay if/when the user attempts to click-drag inside the transparent rectangle, thereby starting a new rectangle.

Illustrative example code:

import tkinter as tk

def fail_click(evt):
    print(evt.x)

root = tk.Tk()

root.attributes('-topmost', True)
root.attributes('-transparentcolor', 'grey')

canvas = tk.Canvas(root, width=300, height=300, bg='grey')
canvas.bind('<Button-1>', fail_click)
canvas.pack()

root.mainloop()

What I expected: An invisible canvas upon which I could draw.

What I got: An empty frame I could reach through to grab whatever is on the other side. This surprised me because I was unaware that 'transparent' == 'not there'. While I can imagine cool things to do with this newfound knowledge, in this case, it's the opposite of what I want.

The question(s):

  1. Is this the intended behavior for GUI windows in general or is this a quirk of Tkinter? In other words, could I solve this problem simply by using a different toolkit, e.g., wxPython or pyQt?

  2. Assuming this is the intended behavior, is there a workaround for getting my invisible canvas to register mouse events. e.g., capturing the click event and redirecting it to where it belongs (the canvas)? It doesn't need to be trivial, I just need a signpost pointing me in the right direction.

Notes:

  • I haven't put a lot of effort into this as it's just a silly side project I'm working on. I just decided to ask the question before I waste time I don't have trying a hundred different things, like learning how to use a new toolkit. And, who knows, maybe it'll help save someone else some time.
  • I've glanced over the code from this answer - https://stackoverflow.com/a/42880450/3602761 - but that's just capturing click events. I need the whole caboodle: Motion, Button-1, B1-Motion, ButtonRelease-1, etc.
  • I'm only using Python and Tkinter here because Python is the language I'm most familiar with and Tkinter is built-in. Feel free to offer suggestions straying from this implementation decision.
Sam
  • 69
  • 1
  • 10
  • Try using `-alpha` instead of `-transparentcolor`. – acw1668 Oct 07 '20 at 00:35
  • @acw1668 Unfortunately, as far as I can tell, `-alpha` affects the toplevel window and all child widgets below it. I still want visual feedback from the rest of the application. – Sam Oct 07 '20 at 04:52
  • 1
    Setting alpha to, for example, 0.5 and you can still see the widgets and the things behind the window at the same time. Another option is to make the root window transparent as your code, but add another border-less `Toplevel` with `alpha` set to 0.01 and overlay that *almost* transparent toplevel window on top of the client area of the root window. Note that you need to move this overlay toplevel along with the root window when the root window is moved. – acw1668 Oct 07 '20 at 05:07
  • I had already played around with the first suggestion and didn't care for the results. The second I had considered, but haven't yet implemented. I'll probably give it a go later this afternoon if I have time. The overlay will be fullscreen so movement won't be an issue. In any case, useful suggestions. Thanks. – Sam Oct 07 '20 at 14:04

1 Answers1

0

If you want partially transparent write the number as you wish instead of 0 in alpha

import tkinter as tk

def fail_click(evt):
    print(evt.x)

root = tk.Tk()

root.attributes('-topmost', True)
root.attributes('-alpha', 0) 

canvas = tk.Canvas(root, width=300, height=300, bg='grey')
canvas.bind('<Button-1>', fail_click)
canvas.pack()

root.mainloop()
Naitik Singhal
  • 126
  • 1
  • 4