Merge pull request #2581 from PySimpleGUI/Dev-latest
Window.element_list added. Image defaults to filename='' if nothing s…
This commit is contained in:
		
						commit
						751abed990
					
				
					 1 changed files with 257 additions and 2 deletions
				
			
		
							
								
								
									
										259
									
								
								PySimpleGUI.py
									
										
									
									
									
								
							
							
						
						
									
										259
									
								
								PySimpleGUI.py
									
										
									
									
									
								
							|  | @ -1,6 +1,6 @@ | ||||||
| #!/usr/bin/python3 | #!/usr/bin/python3 | ||||||
| 
 | 
 | ||||||
| version = __version__ = "4.15.1.10  Unreleased - Fix for draw_pixel, fix Multline.update with no value specified, listbox update no longer selects a default, all justifications can be shortened to single letter, fix for debug window closed with Quit button, removed f-string, draw_polygon added, print_to_element added, Listbox.get, Listbox update parm select_mode, check for None when creating Multiline, Element.unbind" | version = __version__ = "4.15.1.11  Unreleased - Fix for draw_pixel, fix Multline.update with no value specified, listbox update no longer selects a default, all justifications can be shortened to single letter, fix for debug window closed with Quit button, removed f-string, draw_polygon added, print_to_element added, Listbox.get, Listbox update parm select_mode, check for None when creating Multiline, Element.unbind, Image now defaults to filename='', added Window.element_list()" | ||||||
| 
 | 
 | ||||||
| port = 'PySimpleGUI' | port = 'PySimpleGUI' | ||||||
| 
 | 
 | ||||||
|  | @ -2908,7 +2908,7 @@ class Image(Element): | ||||||
|         self.tktext_label = None |         self.tktext_label = None | ||||||
|         self.BackgroundColor = background_color |         self.BackgroundColor = background_color | ||||||
|         if data is None and filename is None: |         if data is None and filename is None: | ||||||
|             print('* Warning... no image specified in Image Element! *') |             self.Filename = '' | ||||||
|         self.EnableEvents = enable_events |         self.EnableEvents = enable_events | ||||||
|         self.RightClickMenu = right_click_menu |         self.RightClickMenu = right_click_menu | ||||||
|         self.AnimatedFrames = None |         self.AnimatedFrames = None | ||||||
|  | @ -6370,6 +6370,44 @@ class Window: | ||||||
|                     key_dict[element.Key] = element |                     key_dict[element.Key] = element | ||||||
|         return key_dict |         return key_dict | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     def element_list(self): | ||||||
|  |         """ | ||||||
|  |         Returns a list of all elements in the window | ||||||
|  | 
 | ||||||
|  |         :return: List[Element] - List of all elements in the window and container elements in the window | ||||||
|  |         """ | ||||||
|  |         return self._build_element_list() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def _build_element_list(self): | ||||||
|  |         """ | ||||||
|  |         Used internally only! Not user callable | ||||||
|  |         Builds a dictionary containing all elements with keys for this window. | ||||||
|  |         """ | ||||||
|  |         elem_list = [] | ||||||
|  |         elem_list = self._build_element_list_for_form(self, self, elem_list) | ||||||
|  |         return elem_list | ||||||
|  | 
 | ||||||
|  |     def _build_element_list_for_form(self, top_window, window, elem_list): | ||||||
|  |         """ | ||||||
|  |         Loop through all Rows and all Container Elements for this window and create a list | ||||||
|  |         Note that the calls are recursive as all pathes must be walked | ||||||
|  | 
 | ||||||
|  |         :param top_window: (Window) The highest level of the window | ||||||
|  |         :param window: Union[Column, Frame, TabGroup, Pane, Tab] The "sub-window" (container element) to be searched | ||||||
|  |         :param elem_list: The element list as it currently stands.... used as part of recursive call | ||||||
|  |         :return: List[Element] List of all elements in this sub-window | ||||||
|  |         """ | ||||||
|  |         for row_num, row in enumerate(window.Rows): | ||||||
|  |             for col_num, element in enumerate(row): | ||||||
|  |                 elem_list.append(element) | ||||||
|  |                 if element.Type in (ELEM_TYPE_COLUMN, ELEM_TYPE_FRAME, ELEM_TYPE_TAB_GROUP, ELEM_TYPE_PANE, ELEM_TYPE_TAB): | ||||||
|  |                     elem_list = self._build_element_list_for_form(top_window, element, elem_list) | ||||||
|  |         return elem_list | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     def SaveToDisk(self, filename): |     def SaveToDisk(self, filename): | ||||||
|         """ |         """ | ||||||
|         Saves the values contained in each of the input areas of the form. Basically saves what would be returned |         Saves the values contained in each of the input areas of the form. Basically saves what would be returned | ||||||
|  | @ -6933,6 +6971,218 @@ Window.CloseNonBlockingForm = Window.Close | ||||||
| Window.CloseNonBlocking = Window.Close | Window.CloseNonBlocking = Window.Close | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | # -------------------------------- System Tray Begins Here -------------------------------- # | ||||||
|  | # Feb 2020 - Just starting on this so code commented out for now. Basing on PySimpleGUIQt's implementation / call format | ||||||
|  | 
 | ||||||
|  | # ------------------------------------------------------------------------- # | ||||||
|  | #                       SystemTray - class for implementing a psyeudo tray  # | ||||||
|  | # ------------------------------------------------------------------------- # | ||||||
|  | # class SystemTray: | ||||||
|  | #     def __init__(self, menu=None, filename=None, data=None, data_base64=None, tooltip=None, metadata=None): | ||||||
|  | #         ''' | ||||||
|  | #         SystemTray - create an icon in the system tray | ||||||
|  | #         :param menu: Menu definition | ||||||
|  | #         :param filename: filename for icon | ||||||
|  | #         :param data: in-ram image for icon | ||||||
|  | #         :param data_base64: basee-64 data for icon | ||||||
|  | #         :param tooltip: tooltip string | ||||||
|  | #         ''' | ||||||
|  | #         self.Menu = menu | ||||||
|  | #         self.TrayIcon = None | ||||||
|  | #         self.Shown = False | ||||||
|  | #         self.MenuItemChosen = TIMEOUT_KEY | ||||||
|  | #         self.LastMessage = None | ||||||
|  | #         self.LastTitle = None | ||||||
|  | #         self.metadata = metadata | ||||||
|  | # | ||||||
|  | #         if Window.QTApplication is None: | ||||||
|  | #             Window.QTApplication = QApplication(sys.argv) | ||||||
|  | #         self.App = Window.QTApplication | ||||||
|  | #         self.Widget = self.QWidget = QWidget()              # type: QWidget | ||||||
|  | # | ||||||
|  | #         if filename is None and data is None and data_base64 is None: | ||||||
|  | #             data_base64 = DEFAULT_BASE64_ICON | ||||||
|  | #         qicon = None | ||||||
|  | #         if filename is not None: | ||||||
|  | #             qicon = QIcon(filename) | ||||||
|  | #         elif data is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromRawData(data) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | #         elif data_base64 is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromBase64(data_base64) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | #         if qicon is None: | ||||||
|  | #             PopupError('ERROR - Tray must have one form of Icon specified') | ||||||
|  | #             return | ||||||
|  | #         self.TrayIcon = QSystemTrayIcon(qicon) | ||||||
|  | # | ||||||
|  | #         if self.Menu is not None: | ||||||
|  | #             qmenu = QMenu() | ||||||
|  | #             qmenu.setTitle(self.Menu[0]) | ||||||
|  | #             AddTrayMenuItem(qmenu, self.Menu[1], self) | ||||||
|  | #             self.TrayIcon.setContextMenu(qmenu) | ||||||
|  | # | ||||||
|  | #         if tooltip is not None: | ||||||
|  | #             self.TrayIcon.setToolTip(str(tooltip)) | ||||||
|  | # | ||||||
|  | #         self.TrayIcon.messageClicked.connect(self._message_clicked) | ||||||
|  | #         self.TrayIcon.activated.connect(self._double_clicked) | ||||||
|  | # | ||||||
|  | #         self.TrayIcon.show() | ||||||
|  | # | ||||||
|  | #     def _QT_MenuItemChosenCallback(self, item_chosen): | ||||||
|  | #         self.MenuItemChosen = item_chosen.replace('&','') | ||||||
|  | #         self.App.exit()                         # kick the users out of the mainloop | ||||||
|  | # | ||||||
|  | #     # callback function when message is clicked | ||||||
|  | #     def _message_clicked(self): | ||||||
|  | #         self.MenuItemChosen = EVENT_SYSTEM_TRAY_MESSAGE_CLICKED | ||||||
|  | #         self.App.exit() | ||||||
|  | # | ||||||
|  | # | ||||||
|  | #     def _double_clicked(self, reason): | ||||||
|  | #         # print(reason) | ||||||
|  | #         if reason == QSystemTrayIcon.DoubleClick: | ||||||
|  | #             self.MenuItemChosen = EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED | ||||||
|  | #             self.App.exit() | ||||||
|  | #         if reason == QSystemTrayIcon.Trigger: | ||||||
|  | #             self.MenuItemChosen = EVENT_SYSTEM_TRAY_ICON_ACTIVATED | ||||||
|  | #             self.App.exit() | ||||||
|  | # | ||||||
|  | # | ||||||
|  | #     def Read(self, timeout=None): | ||||||
|  | #         ''' | ||||||
|  | #         Reads the context menu | ||||||
|  | #         :param timeout: Optional.  Any value other than None indicates a non-blocking read | ||||||
|  | #         :return: | ||||||
|  | #         ''' | ||||||
|  | #         if not self.Shown: | ||||||
|  | #             self.Shown = True | ||||||
|  | #             self.TrayIcon.show() | ||||||
|  | #         if timeout is None: | ||||||
|  | #             self.App.exec_() | ||||||
|  | #         elif timeout == 0: | ||||||
|  | #             self.App.processEvents() | ||||||
|  | #         else: | ||||||
|  | #             self.timer = start_systray_read_timer(self, timeout) | ||||||
|  | #             self.App.exec_() | ||||||
|  | # | ||||||
|  | #             if self.timer: | ||||||
|  | #                 stop_timer(self.timer) | ||||||
|  | # | ||||||
|  | #         item = self.MenuItemChosen | ||||||
|  | #         self.MenuItemChosen = TIMEOUT_KEY | ||||||
|  | #         return item | ||||||
|  | # | ||||||
|  | #     def _timer_timeout(self): | ||||||
|  | #         self.App.exit()  # kick the users out of the mainloop | ||||||
|  | # | ||||||
|  | #     def Hide(self): | ||||||
|  | #         self.TrayIcon.hide() | ||||||
|  | # | ||||||
|  | # | ||||||
|  | #     def UnHide(self): | ||||||
|  | #         self.TrayIcon.show() | ||||||
|  | # | ||||||
|  | # | ||||||
|  | #     def ShowMessage(self, title, message, filename=None, data=None, data_base64=None, messageicon=None, time=10000): | ||||||
|  | #         ''' | ||||||
|  | #         Shows a balloon above icon in system tray | ||||||
|  | #         :param title:  Title shown in balloon | ||||||
|  | #         :param message: Message to be displayed | ||||||
|  | #         :param filename: Optional icon filename | ||||||
|  | #         :param data: Optional in-ram icon | ||||||
|  | #         :param data_base64: Optional base64 icon | ||||||
|  | #         :param time: How long to display message in milliseconds | ||||||
|  | #         :return: | ||||||
|  | #         ''' | ||||||
|  | #         qicon = None | ||||||
|  | #         if filename is not None: | ||||||
|  | #             qicon = QIcon(filename) | ||||||
|  | #         elif data is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromRawData(data) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | #         elif data_base64 is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromBase64(data_base64) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | # | ||||||
|  | #         if qicon is not None: | ||||||
|  | #             self.TrayIcon.showMessage(title, message, qicon, time) | ||||||
|  | #         elif messageicon is not None: | ||||||
|  | #             self.TrayIcon.showMessage(title, message, messageicon, time) | ||||||
|  | #         else: | ||||||
|  | #             self.TrayIcon.showMessage(title, message, QIcon(), time) | ||||||
|  | # | ||||||
|  | #         self.LastMessage = message | ||||||
|  | #         self.LastTitle = title | ||||||
|  | #         return self | ||||||
|  | # | ||||||
|  | #     def Close(self): | ||||||
|  | #         ''' | ||||||
|  | # | ||||||
|  | #         :return: | ||||||
|  | #         ''' | ||||||
|  | #         self.Hide() | ||||||
|  | #         # Don't close app because windows could be depending on it | ||||||
|  | #         # self.App.quit() | ||||||
|  | # | ||||||
|  | # | ||||||
|  | #     def Update(self, menu=None, tooltip=None,filename=None, data=None, data_base64=None,): | ||||||
|  | #         ''' | ||||||
|  | #         Updates the menu, tooltip or icon | ||||||
|  | #         :param menu: menu defintion | ||||||
|  | #         :param tooltip: string representing tooltip | ||||||
|  | #         :param filename:  icon filename | ||||||
|  | #         :param data:  icon raw image | ||||||
|  | #         :param data_base64: icon base 64 image | ||||||
|  | #         :return: | ||||||
|  | #         ''' | ||||||
|  | #         # Menu | ||||||
|  | #         if menu is not None: | ||||||
|  | #             self.Menu = menu | ||||||
|  | #             qmenu = QMenu() | ||||||
|  | #             qmenu.setTitle(self.Menu[0]) | ||||||
|  | #             AddTrayMenuItem(qmenu, self.Menu[1], self) | ||||||
|  | #             self.TrayIcon.setContextMenu(qmenu) | ||||||
|  | #         # Tooltip | ||||||
|  | #         if tooltip is not None: | ||||||
|  | #             self.TrayIcon.setToolTip(str(tooltip)) | ||||||
|  | #         # Icon | ||||||
|  | #         qicon = None | ||||||
|  | #         if filename is not None: | ||||||
|  | #             qicon = QIcon(filename) | ||||||
|  | #         elif data is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromRawData(data) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | #         elif data_base64 is not None: | ||||||
|  | #             ba = QtCore.QByteArray.fromBase64(data_base64) | ||||||
|  | #             pixmap = QtGui.QPixmap() | ||||||
|  | #             pixmap.loadFromData(ba) | ||||||
|  | #             qicon = QIcon(pixmap) | ||||||
|  | #         if qicon is not None: | ||||||
|  | #             self.TrayIcon.setIcon(qicon) | ||||||
|  | # | ||||||
|  | #     close = Close | ||||||
|  | #     hide = Hide | ||||||
|  | #     read = Read | ||||||
|  | #     show_message = ShowMessage | ||||||
|  | #     un_hide = UnHide | ||||||
|  | #     update = Update | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # ################################################################################ | # ################################################################################ | ||||||
| # ################################################################################ | # ################################################################################ | ||||||
| #  END OF ELEMENT DEFINITIONS | #  END OF ELEMENT DEFINITIONS | ||||||
|  | @ -6940,6 +7190,10 @@ Window.CloseNonBlocking = Window.Close | ||||||
| # ################################################################################ | # ################################################################################ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # =========================================================================== # | # =========================================================================== # | ||||||
| # Button Lazy Functions so the caller doesn't have to define a bunch of stuff # | # Button Lazy Functions so the caller doesn't have to define a bunch of stuff # | ||||||
| # =========================================================================== # | # =========================================================================== # | ||||||
|  | @ -13303,6 +13557,7 @@ def main(): | ||||||
|     # graph_elem.DrawCircle((200, 200), 50, 'blue') |     # graph_elem.DrawCircle((200, 200), 50, 'blue') | ||||||
|     i = 0 |     i = 0 | ||||||
|     Print('', location=(0, 0), font='Courier 10', size=(100, 20), grab_anywhere=True) |     Print('', location=(0, 0), font='Courier 10', size=(100, 20), grab_anywhere=True) | ||||||
|  |     print(window.element_list()) | ||||||
|     while True:  # Event Loop |     while True:  # Event Loop | ||||||
|         event, values = window.Read(timeout=5) |         event, values = window.Read(timeout=5) | ||||||
|         if event != TIMEOUT_KEY: |         if event != TIMEOUT_KEY: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue