diff --git a/PySimpleGUIWx/PySimpleGUIWx.py b/PySimpleGUIWx/PySimpleGUIWx.py index 8c44dc2b..9df0724d 100644 --- a/PySimpleGUIWx/PySimpleGUIWx.py +++ b/PySimpleGUIWx/PySimpleGUIWx.py @@ -2780,14 +2780,14 @@ class SystemTray: class DragFrame(wx.Frame): - def __init__(self, bind_to): + def __init__(self): wx.Frame.__init__(self, None) - Window.highest_level_app.Bind(wx.EVT_MOTION, self.on_mouse) def on_mouse(self, event): ''' implement dragging ''' + # print('on_mouse') if not event.Dragging(): self._dragPos = None return @@ -3034,11 +3034,14 @@ class Window: self.App.ExitMainLoop() - def autoclose_timer_callback(self, event): - # print('*** AUTOCLOSE TIMEOUT CALLBACK ***') - self.MasterFrame.Close() + def autoclose_timer_callback(self, frame): + # print('*** AUTOCLOSE TIMEOUT CALLBACK ***', frame) + try: + frame.Close() + except: + pass # if user has already closed the frame will get an error + if self.CurrentlyRunningMainloop: - # print("quitting window") self.App.ExitMainLoop() @@ -5168,17 +5171,20 @@ def StartupTK(window): app = Window.highest_level_app if window.GrabAnywhere: - frame = DragFrame(app) + frame = DragFrame() else: frame = wx.Frame(None, title=window.Title) panel = wx.Panel(frame) + if window.GrabAnywhere: + panel.Bind(wx.EVT_MOTION, frame.on_mouse) + + window.App = app window.MasterFrame = frame window.MasterPanel = panel window.MasterFrame.panel = panel - frame.Bind(wx.EVT_CLOSE, window.OnClose) if window.WindowIcon: @@ -5255,8 +5261,8 @@ def StartupTK(window): timer = None if window.AutoClose: - window.timer = wx.Timer(window.App, id=1234 ) - window.App.Bind(wx.EVT_TIMER, window.autoclose_timer_callback, id=1234) + window.timer = wx.Timer(window.App, id=Window.NumOpenWindows) + window.App.Bind(wx.EVT_TIMER, lambda frame: window.autoclose_timer_callback(window.MasterFrame), id=Window.NumOpenWindows) window.timer.Start(milliseconds=window.AutoCloseDuration*1000, oneShot=wx.TIMER_ONE_SHOT) # ------------------------------------ MAINLOOP ------------------------------------ if not window.NonBlocking: @@ -5472,11 +5478,12 @@ def GetComplimentaryHex(color): # ======================== EasyPrint =====# # ===================================================# + class DebugWin(): debug_window = None def __init__(self, size=(None, None), location=(None, None), font=None, no_titlebar=False, no_button=False, - grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=True): + grab_anywhere=False, keep_on_top=False, title=None, do_not_reroute_stdout=False): # Show a form that's a running counter self.size = size self.location = location @@ -5488,9 +5495,9 @@ class DebugWin(): self.do_not_reroute_stdout = do_not_reroute_stdout win_size = size if size != (None, None) else DEFAULT_DEBUG_WINDOW_SIZE - self.window = Window('Debug Window', no_titlebar=no_titlebar, auto_size_text=True, location=location, + self.window = Window(title=title or 'Debug Window', no_titlebar=no_titlebar, auto_size_text=True, location=location, font=font or ('Courier New', 10), grab_anywhere=grab_anywhere, keep_on_top=keep_on_top) - self.output_element = Multiline(size=win_size, autoscroll=True, key='_MULTILINE_') if do_not_reroute_stdout else Output(size=win_size) + self.output_element = Multiline(size=win_size, key='_MULTILINE_') if do_not_reroute_stdout else Output(size=win_size) if no_button: self.layout = [[self.output_element]] @@ -5501,13 +5508,14 @@ class DebugWin(): ] self.window.AddRows(self.layout) self.window.Read(timeout=0) # Show a non-blocking form, returns immediately + Window.active_popups[self.window] = 'debug window' return def Print(self, *args, end=None, sep=None): sepchar = sep if sep is not None else ' ' endchar = end if end is not None else '\n' - if self.window is None: # if window was destroyed alread re-open it + if self.window is None: # if window was destroyed already, just print self.__init__(size=self.size, location=self.location, font=self.font, no_titlebar=self.no_titlebar, no_button=self.no_button, grab_anywhere=self.grab_anywhere, keep_on_top=self.keep_on_top, do_not_reroute_stdout=self.do_not_reroute_stdout) event, values = self.window.Read(timeout=0) if event == 'Quit' or event is None: @@ -5534,7 +5542,7 @@ def PrintClose(): def EasyPrint(*args, size=(None, None), end=None, sep=None, location=(None, None), font=None, no_titlebar=False, - no_button=False, grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=False): + no_button=False, grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=True): if DebugWin.debug_window is None: @@ -5543,19 +5551,6 @@ def EasyPrint(*args, size=(None, None), end=None, sep=None, location=(None, None DebugWin.debug_window.Print(*args, end=end, sep=sep) -def PrintClose(): - EasyPrintClose() - - -def EasyPrint(*args, size=(None, None), end=None, sep=None, location=(None, None), font=None, no_titlebar=False, - no_button=False, grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=False): - - - if DebugWin.debug_window is None: - DebugWin.debug_window = DebugWin(size=size, location=location, font=font, no_titlebar=no_titlebar, - no_button=no_button, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, do_not_reroute_stdout=do_not_reroute_stdout) - DebugWin.debug_window.Print(*args, end=end, sep=sep) - Print = EasyPrint eprint = EasyPrint @@ -6124,9 +6119,9 @@ def ObjToString(obj, extra=' '): # ----------------------------------- The mighty Popup! ------------------------------------------------------------ # -def Popup(*args, button_color=None, background_color=None, text_color=None, button_type=POPUP_BUTTONS_OK, - auto_close=False, auto_close_duration=None, custom_text=(None, None), non_blocking=False, - icon=DEFAULT_WINDOW_ICON, line_width=None, + +def Popup(*args, title=None, button_color=None, background_color=None, text_color=None, button_type=POPUP_BUTTONS_OK, + auto_close=False, auto_close_duration=None, custom_text=(None, None), non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None)): """ Popup - Display a popup box with as many parms as you wish to include @@ -6155,8 +6150,8 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt local_line_width = line_width else: local_line_width = MESSAGE_BOX_LINE_WIDTH - title = args_to_print[0] if args_to_print[0] is not None else 'None' - window = Window(title, auto_size_text=True, background_color=background_color, button_color=button_color, + _title = title if title is not None else args_to_print[0] + window = Window(_title, auto_size_text=True, background_color=background_color, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location) max_line_total, total_lines = 0, 0 @@ -6185,15 +6180,11 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt # show either an OK or Yes/No depending on paramater if custom_text != (None, None): if type(custom_text) is not tuple: - window.AddRow(PopupButton(custom_text, size=(len(custom_text), 1), button_color=button_color, focus=True, - bind_return_key=True)) + window.AddRow(PopupButton(custom_text,size=(len(custom_text),1), button_color=button_color, focus=True, bind_return_key=True)) elif custom_text[1] is None: - window.AddRow( - PopupButton(custom_text[0], size=(len(custom_text[0]), 1), button_color=button_color, focus=True, - bind_return_key=True)) + window.AddRow(PopupButton(custom_text[0],size=(len(custom_text[0]),1), button_color=button_color, focus=True, bind_return_key=True)) else: - window.AddRow(PopupButton(custom_text[0], button_color=button_color, focus=True, bind_return_key=True, - size=(len(custom_text[0]), 1)), + window.AddRow(PopupButton(custom_text[0], button_color=button_color, focus=True, bind_return_key=True, size=(len(custom_text[0]), 1)), PopupButton(custom_text[1], button_color=button_color, size=(len(custom_text[0]), 1))) elif button_type is POPUP_BUTTONS_YES_NO: window.AddRow(PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True, pad=((20, 5), 3), @@ -6567,10 +6558,11 @@ def PopupYesNo(*args, button_color=None, background_color=None, text_color=None, # The PopupGet_____ functions - Will return user input # ############################################################################## + # --------------------------- PopupGetFolder --------------------------- -def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), button_color=None, +def PopupGetFolder(message, title=None, default_path='', no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None, icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), initial_folder=None): """ @@ -6593,28 +6585,23 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), if no_window: - if Window.NumOpenWindows: - root = tk.Toplevel() - else: - root = tk.Tk() - try: - root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint' - except: - pass - folder_name = tk.filedialog.askdirectory() # show the 'get folder' dialog box - root.destroy() + if Window.QTApplication is None: + Window.QTApplication = QApplication(sys.argv) + + folder_name = QFileDialog.getExistingDirectory(dir=initial_folder) return folder_name layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)], [InputText(default_text=default_path, size=size), FolderBrowse(initial_folder=initial_folder)], - [CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]] + [CloseButton('Ok', size=(60, 20), bind_return_key=True), CloseButton('Cancel', size=(60, 20))]] - window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, + _title = title if title is not None else message + window = Window(title=_title, icon=icon, auto_size_text=True, button_color=button_color, background_color=background_color, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location) - (button, input_values) = window.LayoutAndRead(layout) + (button, input_values) = window.Layout(layout).Read() if button != 'Ok': return None @@ -6625,7 +6612,7 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), # --------------------------- PopupGetFile --------------------------- -def PopupGetFile(message, default_path='', default_extension='', save_as=False, file_types=(("ALL Files", "*.*"),), +def PopupGetFile(message, title=None, default_path='', default_extension='', save_as=False, file_types=(("ALL Files", "*"),), no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None, icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), initial_folder=None): @@ -6650,37 +6637,34 @@ def PopupGetFile(message, default_path='', default_extension='', save_as=False, :return: string representing the path chosen, None if cancelled or window closed with X """ - if no_window: - if Window.NumOpenWindows: - root = tk.Toplevel() - else: - root = tk.Tk() - try: - root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint' - except: - pass + if Window.QTApplication is None: + Window.QTApplication = QApplication(sys.argv) + if save_as: - filename = tk.filedialog.asksaveasfilename(filetypes=file_types, - defaultextension=default_extension) # show the 'get file' dialog box + qt_types = convert_tkinter_filetypes_to_qt(file_types) + filename = QFileDialog.getSaveFileName(dir=initial_folder, filter=qt_types) else: - filename = tk.filedialog.askopenfilename(filetypes=file_types, - defaultextension=default_extension) # show the 'get file' dialog box - root.destroy() - return filename + qt_types = convert_tkinter_filetypes_to_qt(file_types) + filename = QFileDialog.getOpenFileName(dir=initial_folder, filter=qt_types) + return filename[0] + browse_button = SaveAs(file_types=file_types, initial_folder=initial_folder) if save_as else FileBrowse( file_types=file_types, initial_folder=initial_folder) layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)], - [InputText(default_text=default_path, size=size), browse_button], - [CloseButton('Ok', size=(6, 1), bind_return_key=True), CloseButton('Cancel', size=(6, 1))]] + [InputText(default_text=default_path, size=(30,1)), browse_button], + [CButton('Ok', size=(60, 20), bind_return_key=True), CButton('Cancel', size=(60, 20))]] - window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, font=font, + _title = title if title is not None else message + + window = Window(title=_title, icon=icon, auto_size_text=True, button_color=button_color, font=font, background_color=background_color, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location) (button, input_values) = window.Layout(layout).Read() + # window.Close() if button != 'Ok': return None else: @@ -6690,7 +6674,7 @@ def PopupGetFile(message, default_path='', default_extension='', save_as=False, # --------------------------- PopupGetText --------------------------- -def PopupGetText(message, default_text='', password_char='', size=(None, None), button_color=None, +def PopupGetText(message, title=None, default_text='', password_char='', size=(None, None), button_color=None, background_color=None, text_color=None, icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None)): """ @@ -6713,9 +6697,11 @@ def PopupGetText(message, default_text='', password_char='', size=(None, None), layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color, font=font)], [InputText(default_text=default_text, size=size, password_char=password_char)], - [CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]] + [CloseButton('Ok', size=(60, 20), bind_return_key=True), CloseButton('Cancel', size=(60, 20))]] - window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, + _title = title if title is not None else message + + window = Window(title=_title, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location) diff --git a/PySimpleGUIWx/readme.md b/PySimpleGUIWx/readme.md index b8a72b5d..12b5f627 100644 --- a/PySimpleGUIWx/readme.md +++ b/PySimpleGUIWx/readme.md @@ -16,7 +16,7 @@ ![Python Version](https://img.shields.io/badge/Python-3.x-yellow.svg) -![Python Version](https://img.shields.io/badge/PySimpleGUIWx_For_Python_3.x_Version-0.3.0-orange.svg?longCache=true&style=for-the-badge) +![Python Version](https://img.shields.io/badge/PySimpleGUIWx_For_Python_3.x_Version-0.4.0-orange.svg?longCache=true&style=for-the-badge) @@ -26,7 +26,7 @@ The WxPython port of PySimpleGUI - ## The Engineering Pre-Release Version 0.3.0 + ## The Engineering Pre-Release Version 0.4.0 [Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142) @@ -165,6 +165,11 @@ If you want to change the separator characters from :: top something else,change When a menu item has a key and it is chosen, then entire string is returned. If Hide were selected, then Hide::key would be returned from the Read. Note that the shortcut character & is NOT returned from Reads. +## Popups + +Starting with release 0.4.0, most of the Popup functions work. This means you can do things like show information in a window when there's a choice made in a System Tray menu. Or if your program finds some event it wishes to inform the user about. For example, when new Issues are posted on a GitHub project. + + # Release Notes: ### 0.1.0 - 25-Dec-2018 @@ -191,6 +196,25 @@ When a menu item has a key and it is chosen, then entire string is returned. If * Popups +### 0.4.0 PySimpleGUIWx 30-Dec-2018 + +* Text Element - colors, font work +* Text Update method works +* Button - Close button implemented +* Button - Implemented basic button, correctly presented Values on Read +* Button - Can now set font +* Changed overall "App" variable usage for better mainloop control +* Windows - Timeouts and non-blocking Reads work +* Windows - Autoclose works +* Windows - Non-blocking calls supported (timeout=0) +* Windows - Grab anywhere works +* Windows - No title-bar works +* Windows - Location and Size working correctly +* Correctly adding element padding to Text, Input, Buttons +* Popups - most Popups work (except for the input type that involve folders) + + + # Design # Author Mike B.