Compare commits

...
Sign in to create a new pull request.

10 commits

Author SHA1 Message Date
MikeTheWatchGuy
e1daf1046f
Merge pull request #1432 from deajan/calendar_improvements
Allow calendar button locale, format, and default icon usage
2019-05-30 10:35:01 -04:00
Orsiris de Jong
8ff3c80f23
Fix default PySimpleGUI icon never used in CalendarButton 2019-05-19 14:18:58 +02:00
MikeTheWatchGuy
28eed8751c Overhaul to correctly handle tooltips, buttons, etc. Cleanup in a major way 2019-05-18 15:13:47 -04:00
Orsiris de Jong
f563f01ed8
Fix indentation error while merging PRs 2019-05-17 13:18:30 +02:00
Orsiris de Jong
4d137e19c4
Merge PR #1433 to avoid conflicts as same lines affected 2019-05-17 13:17:24 +02:00
Orsiris de Jong
7aa110b1fe
Multiple improvements on CalendarButton
Allow passing optional format argument (as of datetime.strftime() format given https://docs.python.org/3.6/library/datetime.html?highlight=strftime#strftime-strptime-behavior)
Also use current timestamp when updating calendar instead of 00:00:00
2019-05-17 13:11:55 +02:00
Orsiris de Jong
e35fdd8518
Allow calendar button locale
Fixes half of #977
2019-05-17 12:12:38 +02:00
PySimpleGUI
2780e20262
Merge pull request #1401 from musteresel/fix-graph-images-memleak
Fix memory leak due to Images of Graph
2019-05-15 10:16:46 -04:00
Daniel Jour
78c84b9f8f Fix memory leak due to Images of Graph (PySimpleGui27)
- Graph used a list self.Images to which new images where appended on
   DrawImage.  Neither in DeleteFigure nor in Erase were any elements
   removed from that list.  Thus any added image was kept in memory as
   long as the corresponding Graph was; even if it wasn't used
   anymore.

 - Even though self.Images is not referred to in any other way,
   removing the list completely does not work; the result
   is that no images are drawn on the Graph.

 - The implemented solution uses a dictionary (id -> image) to keep
   only used images in self.Images.
2019-05-13 22:51:23 +02:00
Daniel Jour
bdaf9503ee Fix memory leak due to Images of Graph
- Graph used a list self.Images to which new images where appended on
   DrawImage.  Neither in DeleteFigure nor in Erase were any elements
   removed from that list.  Thus any added image was kept in memory as
   long as the corresponding Graph was; even if it wasn't used
   anymore.

 - Even though self.Images is not referred to in any other way,
   removing the list completely does not work; the result
   is that no images are drawn on the Graph.

 - The implemented solution uses a dictionary (id -> image) to keep
   only used images in self.Images.
2019-05-13 22:32:29 +02:00
3 changed files with 40 additions and 15 deletions

View file

@ -1632,10 +1632,19 @@ class Button(Element):
root = tk.Toplevel() root = tk.Toplevel()
root.title('Calendar Chooser') root.title('Calendar Chooser')
root.wm_attributes("-topmost", 1) root.wm_attributes("-topmost", 1)
self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element, close_when_chosen=self.CalendarCloseWhenChosen, default_date=self.DefaultDate_M_D_Y ) self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element, close_when_chosen=self.CalendarCloseWhenChosen, default_date=self.DefaultDate_M_D_Y, locale=self.CalendarLocale, format=self.CalendarFormat)
self.TKCal.pack(expand=1, fill='both') self.TKCal.pack(expand=1, fill='both')
root.update() root.update()
if type(Window.user_defined_icon) is bytes:
calendar_icon = tkinter.PhotoImage(data=Window.user_defined_icon)
else:
calendar_icon = tkinter.PhotoImage(data=DEFAULT_BASE64_ICON)
try:
root.tk.call('wm', 'iconphoto', root._w, calendar_icon)
except:
pass
if should_submit_window: if should_submit_window:
self.ParentForm.LastButtonClicked = target_element.Key self.ParentForm.LastButtonClicked = target_element.Key
self.ParentForm.FormRemainedOpen = True self.ParentForm.FormRemainedOpen = True
@ -2033,7 +2042,7 @@ class Graph(Element):
self.DragSubmits = drag_submits self.DragSubmits = drag_submits
self.ClickPosition = (None, None) self.ClickPosition = (None, None)
self.MouseButtonDown = False self.MouseButtonDown = False
self.Images = [] self.Images = {}
self.RightClickMenu = right_click_menu self.RightClickMenu = right_click_menu
super().__init__(ELEM_TYPE_GRAPH, background_color=background_color, size=canvas_size, pad=pad, key=key, super().__init__(ELEM_TYPE_GRAPH, background_color=background_color, size=canvas_size, pad=pad, key=key,
@ -2188,9 +2197,9 @@ class Graph(Element):
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
print('Call Window.Finalize() prior to this operation') print('Call Window.Finalize() prior to this operation')
return None return None
self.Images.append(image)
try: # in case closed with X try: # in case closed with X
id = self._TKCanvas2.create_image(converted_point, image=image, anchor=tk.NW) id = self._TKCanvas2.create_image(converted_point, image=image, anchor=tk.NW)
self.Images[id] = image
except: except:
id = None id = None
return id return id
@ -2202,6 +2211,7 @@ class Graph(Element):
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
print('Call Window.Finalize() prior to this operation') print('Call Window.Finalize() prior to this operation')
return None return None
self.Images = {}
try: # in case window was closed with X try: # in case window was closed with X
self._TKCanvas2.delete('all') self._TKCanvas2.delete('all')
except: except:
@ -2210,6 +2220,7 @@ class Graph(Element):
def DeleteFigure(self, id): def DeleteFigure(self, id):
try: try:
del self.Images[id]
self._TKCanvas2.delete(id) self._TKCanvas2.delete(id)
except: except:
print('DeleteFigure - bad ID {}'.format(id)) print('DeleteFigure - bad ID {}'.format(id))
@ -2942,6 +2953,9 @@ class TKCalendar(ttk.Frame):
locale = kw.pop('locale', None) locale = kw.pop('locale', None)
sel_bg = kw.pop('selectbackground', '#ecffc4') sel_bg = kw.pop('selectbackground', '#ecffc4')
sel_fg = kw.pop('selectforeground', '#05640e') sel_fg = kw.pop('selectforeground', '#05640e')
self.format = kw.pop('format')
if self.format is None:
self.format = '%Y-%m-%d %H:%M:%S'
self._date = self.datetime(year, month, default_day or 1) self._date = self.datetime(year, month, default_day or 1)
self._selection = None # no date selected self._selection = None # no date selected
@ -3095,8 +3109,9 @@ class TKCalendar(ttk.Frame):
self._selection = (text, item, column) self._selection = (text, item, column)
self._show_selection(text, bbox) self._show_selection(text, bbox)
year, month = self._date.year, self._date.month year, month = self._date.year, self._date.month
now = self.datetime.now()
try: try:
self._TargetElement.Update(self.datetime(year, month, int(self._selection[0]))) self._TargetElement.Update(self.datetime(year, month, int(self._selection[0]), now.hour, now.minute, now.second).strftime(self.format))
if self._TargetElement.ChangeSubmits: if self._TargetElement.ChangeSubmits:
self._TargetElement.ParentForm.LastButtonClicked = self._TargetElement.Key self._TargetElement.ParentForm.LastButtonClicked = self._TargetElement.Key
self._TargetElement.ParentForm.FormRemainedOpen = True self._TargetElement.ParentForm.FormRemainedOpen = True
@ -4418,7 +4433,7 @@ def DummyButton(button_text, image_filename=None, image_data=None, image_size=(N
def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True, default_date_m_d_y=(None,None,None), image_filename=None, image_data=None, image_size=(None, None), def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True, default_date_m_d_y=(None,None,None), image_filename=None, image_data=None, image_size=(None, None),
image_subsample=None, tooltip=None, border_width=None, size=(None, None), auto_size_button=None, image_subsample=None, tooltip=None, border_width=None, size=(None, None), auto_size_button=None,
button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None, button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None,
key=None): key=None, locale=None, format=None):
button = Button(button_text=button_text, button_type=BUTTON_TYPE_CALENDAR_CHOOSER, target=target, button = Button(button_text=button_text, button_type=BUTTON_TYPE_CALENDAR_CHOOSER, target=target,
image_filename=image_filename, image_data=image_data, image_size=image_size, image_filename=image_filename, image_data=image_data, image_size=image_size,
image_subsample=image_subsample, border_width=border_width, tooltip=tooltip, size=size, image_subsample=image_subsample, border_width=border_width, tooltip=tooltip, size=size,
@ -4426,6 +4441,8 @@ def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True
bind_return_key=bind_return_key, focus=focus, pad=pad, key=key) bind_return_key=bind_return_key, focus=focus, pad=pad, key=key)
button.CalendarCloseWhenChosen = close_when_date_chosen button.CalendarCloseWhenChosen = close_when_date_chosen
button.DefaultDate_M_D_Y = default_date_m_d_y button.DefaultDate_M_D_Y = default_date_m_d_y
button.CalendarLocale = locale
button.CalendarFormat = format
return button return button

View file

@ -2043,7 +2043,7 @@ class Graph(Element):
self.DragSubmits = drag_submits self.DragSubmits = drag_submits
self.ClickPosition = (None, None) self.ClickPosition = (None, None)
self.MouseButtonDown = False self.MouseButtonDown = False
self.Images = [] self.Images = {}
self.RightClickMenu = right_click_menu self.RightClickMenu = right_click_menu
super().__init__(ELEM_TYPE_GRAPH, background_color=background_color, size=canvas_size, pad=pad, key=key, super().__init__(ELEM_TYPE_GRAPH, background_color=background_color, size=canvas_size, pad=pad, key=key,
@ -2198,9 +2198,9 @@ class Graph(Element):
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
print('Call Window.Finalize() prior to this operation') print('Call Window.Finalize() prior to this operation')
return None return None
self.Images.append(image)
try: # in case closed with X try: # in case closed with X
id = self._TKCanvas2.create_image(converted_point, image=image, anchor=tk.NW) id = self._TKCanvas2.create_image(converted_point, image=image, anchor=tk.NW)
self.Images[id] = image
except: except:
id = None id = None
return id return id
@ -2212,6 +2212,7 @@ class Graph(Element):
print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***')
print('Call Window.Finalize() prior to this operation') print('Call Window.Finalize() prior to this operation')
return None return None
self.Images = {}
try: # in case window was closed with X try: # in case window was closed with X
self._TKCanvas2.delete('all') self._TKCanvas2.delete('all')
except: except:
@ -2220,6 +2221,7 @@ class Graph(Element):
def DeleteFigure(self, id): def DeleteFigure(self, id):
try: try:
del self.Images[id]
self._TKCanvas2.delete(id) self._TKCanvas2.delete(id)
except: except:
print('DeleteFigure - bad ID {}'.format(id)) print('DeleteFigure - bad ID {}'.format(id))

View file

@ -1,16 +1,17 @@
#!/usr/bin/env python #!/usr/bin/env python
import PySimpleGUIWeb as sg import PySimpleGUIWeb as sg
# import PySimpleGUI as sg
""" """
Shows a big chart of colors... give it a few seconds to create it Shows a big chart of colors...
Once large window is shown, you can click on any color and another window will popup Once large window is shown, you can click on any color and another window will popup
showing both white and black text on that color showing both white and black text on that color
Uses TOOLTIPS to show the hex values for the colors. Hover over a color and a tooltip will show you the RGB Uses TOOLTIPS to show the hex values for the colors. Hover over a color and a tooltip will show you the RGB
You will find the list of tkinter colors here: You will find the list of tkinter colors here:
http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm
Really shows off the PySimpleGUIWeb capabilities
""" """
color_map = { color_map = {
@ -667,11 +668,19 @@ color_map = {
} }
def detailed_view(window):
layout2 = [[sg.Button(event, button_color=('white', color_map[event]), key=event, tooltip=color_map[color]),
sg.Button(event, button_color=('black', color_map[event]), key=event+'1', tooltip=color_map[color])],
[sg.Txt('Hover over button to see color value. Click to clocse and return to main interface.')], ]
sg.Window('Buttons with white and black text', layout2, keep_on_top=True).Read()
window.Close()
return
sg.SetOptions(button_element_size=(16,1), auto_size_buttons=False, border_width=0, tooltip_time=100) sg.SetOptions(button_element_size=(16,1), auto_size_buttons=False, border_width=0, tooltip_time=100)
#start layout with the tittle #start layout with the tittle
layout = [[sg.Text('Hover mouse to see RGB value', layout = [[sg.Text('Hover mouse to see RGB value. Click to see Button with White or Black text.',
text_color='blue', text_color='blue',
font=('Hevletica', 20), font=('Hevletica', 20),
relief=sg.RELIEF_SUNKEN, relief=sg.RELIEF_SUNKEN,
@ -692,12 +701,9 @@ for rows in range(40):
pass pass
layout.append(row) layout.append(row)
window = sg.Window('Color Viewer', font=('any 12'), default_button_element_size=(12,1), element_padding=(0,0)).Layout(layout)
# -- Event loop --
while True: while True:
window = sg.Window('Color Viewer', layout, font=('any 12'), default_button_element_size=(12,1), element_padding=(0,0))
event, values = window.Read() event, values = window.Read()
if event is None: if event is None:
break break
detailed_view(window)
window.Close()