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:
commit
3952e1a438
|
@ -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,20 +34,19 @@ 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))]]
|
||||||
|
|
||||||
window = sg.Window("Drawing and Moving Stuff Around", layout, finalize=True)
|
window = sg.Window("Drawing and Moving Stuff Around", layout, finalize=True)
|
||||||
|
|
||||||
# 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:
|
||||||
|
@ -114,25 +105,28 @@ def main():
|
||||||
for fig in drag_figures:
|
for fig in drag_figures:
|
||||||
graph.send_figure_to_back(fig)
|
graph.send_figure_to_back(fig)
|
||||||
window["-INFO-"].update(value=f"mouse {values['-GRAPH-']}")
|
window["-INFO-"].update(value=f"mouse {values['-GRAPH-']}")
|
||||||
elif event.endswith('+UP'): # The drawing has ended because mouse up
|
elif event.endswith('+UP'): # The drawing has ended because mouse up
|
||||||
window["-INFO-"].update(value=f"grabbed rectangle from {start_point} to {end_point}")
|
window["-INFO-"].update(value=f"grabbed rectangle from {start_point} to {end_point}")
|
||||||
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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue