Merge pull request #6382 from PySimpleGUI/Dev-latest

Addition of right click menu erase, save image and display of crosshairs
This commit is contained in:
PySimpleGUI 2023-05-18 12:05:22 -04:00 committed by GitHub
commit 3952e1a438
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 28 additions and 34 deletions

View File

@ -1,5 +1,4 @@
import PySimpleGUI as sg import PySimpleGUI as sg
from PIL import ImageGrab
""" """
Demo - Drawing and moving demo Demo - Drawing and moving demo
@ -7,22 +6,9 @@ from PIL import ImageGrab
This demo shows how to use a Graph Element to (optionally) display an image and then use the This demo shows how to use a Graph Element to (optionally) display an image and then use the
mouse to "drag" and draw rectangles and circles. mouse to "drag" and draw rectangles and circles.
Copyright 2020 PySimpleGUI.org Copyright 2020, 2021, 2022, 2023 PySimpleGUI.org
""" """
def save_element_as_file(element, filename):
"""
Saves any element as an image file. Element needs to have an underlyiong Widget available (almost if not all of them do)
:param element: The element to save
:param filename: The filename to save to. The extension of the filename determines the format (jpg, png, gif, ?)
"""
widget = element.Widget
box = (widget.winfo_rootx(), widget.winfo_rooty(), widget.winfo_rootx() + widget.winfo_width(), widget.winfo_rooty() + widget.winfo_height())
grab = ImageGrab.grab(bbox=box)
grab.save(filename)
def main(): def main():
sg.theme('Dark Blue 3') sg.theme('Dark Blue 3')
@ -38,7 +24,6 @@ def main():
[sg.R('Bring to front', 1, key='-FRONT-', enable_events=True)], [sg.R('Bring to front', 1, key='-FRONT-', enable_events=True)],
[sg.R('Move Everything', 1, key='-MOVEALL-', enable_events=True)], [sg.R('Move Everything', 1, key='-MOVEALL-', enable_events=True)],
[sg.R('Move Stuff', 1, key='-MOVE-', enable_events=True)], [sg.R('Move Stuff', 1, key='-MOVE-', enable_events=True)],
[sg.B('Save Image', key='-SAVE-')],
] ]
layout = [[sg.Graph( layout = [[sg.Graph(
@ -49,7 +34,8 @@ def main():
enable_events=True, enable_events=True,
background_color='lightblue', background_color='lightblue',
drag_submits=True, drag_submits=True,
right_click_menu=[[],['Erase item',]] motion_events=True,
right_click_menu=[[''],['Erase item','Send to back']]
), sg.Col(col, key='-COL-') ], ), sg.Col(col, key='-COL-') ],
[sg.Text(key='-INFO-', size=(60, 1))]] [sg.Text(key='-INFO-', size=(60, 1))]]
@ -58,11 +44,9 @@ def main():
# get the graph element for ease of use later # get the graph element for ease of use later
graph = window["-GRAPH-"] # type: sg.Graph graph = window["-GRAPH-"] # type: sg.Graph
graph.draw_image(data=logo200, location=(0,400)) graph.draw_image(data=logo200, location=(0,400))
dragging = False dragging = False
start_point = end_point = prior_rect = None start_point = end_point = prior_rect = None
# graph.bind('<Button-3>', '+RIGHT+') crosshair_lines = []
while True: while True:
event, values = window.read() event, values = window.read()
print(event, values) print(event, values)
@ -73,7 +57,14 @@ def main():
graph.set_cursor(cursor='fleur') # not yet released method... coming soon! graph.set_cursor(cursor='fleur') # not yet released method... coming soon!
elif not event.startswith('-GRAPH-'): elif not event.startswith('-GRAPH-'):
graph.set_cursor(cursor='left_ptr') # not yet released method... coming soon! graph.set_cursor(cursor='left_ptr') # not yet released method... coming soon!
if event.endswith('+MOVE'):
window["-INFO-"].update(value=f"mouse {values['-GRAPH-']}")
# Delete crosshairs if any exists
if len(crosshair_lines):
for fig in crosshair_lines:
graph.delete_figure(fig)
crosshair_lines = []
window.refresh()
if event == "-GRAPH-": # if there's a "Graph" event, then it's a mouse if event == "-GRAPH-": # if there's a "Graph" event, then it's a mouse
x, y = values["-GRAPH-"] x, y = values["-GRAPH-"]
if not dragging: if not dragging:
@ -119,20 +110,23 @@ def main():
start_point, end_point = None, None # enable grabbing a new rect start_point, end_point = None, None # enable grabbing a new rect
dragging = False dragging = False
prior_rect = None prior_rect = None
elif event.endswith('+RIGHT+'): # Righ click # elif event.endswith('+RIGHT+'): # Right click
window["-INFO-"].update(value=f"Right clicked location {values['-GRAPH-']}") # window["-INFO-"].update(value=f"Right clicked location {values['-GRAPH-']}")
elif event.endswith('+MOTION+'): # Righ click # elif event.endswith('+MOTION+'): # Right click
window["-INFO-"].update(value=f"mouse freely moving {values['-GRAPH-']}") # window["-INFO-"].update(value=f"mouse freely moving {values['-GRAPH-']}")
elif event == '-SAVE-': elif event == 'Send to back': # Right clicked menu item
# filename = sg.popup_get_file('Choose file (PNG, JPG, GIF) to save to', save_as=True) figures = graph.get_figures_at_location(values["-GRAPH-"]) # get items in front-to-back order
filename=r'test.jpg' if figures: # make sure at least 1 item found
save_element_as_file(window['-GRAPH-'], filename) graph.send_figure_to_back(figures[-1]) # get the last item which will be the top-most
elif event == 'Erase item': elif event == 'Erase item':
window["-INFO-"].update(value=f"Right click erase at {values['-GRAPH-']}") window["-INFO-"].update(value=f"Right click erase at {values['-GRAPH-']}")
if values['-GRAPH-'] != (None, None): if values['-GRAPH-'] != (None, None):
drag_figures = graph.get_figures_at_location(values['-GRAPH-']) figures = graph.get_figures_at_location(values['-GRAPH-'])
for figure in drag_figures: if figures:
graph.delete_figure(figure) graph.delete_figure(figures[-1]) # delete the one on top
location = values['-GRAPH-']
crosshair_lines = [graph.draw_line((location[0], 0), (location[0], 800), color='red'),
graph.draw_line((0, location[1]), (800, location[1]), color='red')]
window.close() window.close()