Permalink
Browse files

Multi-window support!!

  • Loading branch information...
MikeTheWatchGuy committed Feb 8, 2019
1 parent 5020aa7 commit bf2da43a4813b137066198b7373247fa7028d946
Showing with 61 additions and 101 deletions.
  1. +61 −101 PySimpleGUIWeb/PySimpleGUIWeb.py
@@ -442,7 +442,7 @@ def Update(self, widget, background_color=None, text_color=None, font=None, visi
if visible is False:
widget.attributes['hidden'] = 'true'
elif visible is True:
widget.attributes['hidden'] = 'false'
del(widget.attributes['hidden'])

def __del__(self):
pass
@@ -1482,14 +1482,7 @@ def ButtonCallBack(self, event):
self.ParentForm.FormRemainedOpen = True
element_callback_quit_mainloop(self)
elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop
if self.Key is not None:
self.ParentForm.LastButtonClicked = self.Key
else:
self.ParentForm.LastButtonClicked = self.ButtonText
if self.ParentForm.CurrentlyRunningMainloop: # if this window is running the mainloop, kick out
self.ParentForm.App.ExitMainLoop()
self.ParentForm.IgnoreClose = True
self.ParentForm.MasterFrame.Close()
element_callback_quit_mainloop(self)
self.ParentForm._Close()
Window.DecrementOpenCount()
elif self.BType == BUTTON_TYPE_CALENDAR_CHOOSER: # this is a return type button so GET RESULTS and destroy window
@@ -2592,6 +2585,8 @@ class Window:
stdout_is_rerouted = False
stdout_location = None
port_number = 6900
active_windows = [ ] # type: Window []
App = None

def __init__(self, title, default_element_size=DEFAULT_ELEMENT_SIZE, default_button_element_size=(None, None),
auto_size_text=None, auto_size_buttons=None, location=(None, None), size=(None, None),
@@ -2693,6 +2688,7 @@ def __init__(self, title, default_element_size=DEFAULT_ELEMENT_SIZE, default_but
self.thread_id = None
self.App = None # type: Window.MyApp
self.MessageQueue = Queue()
self.master_widget = None

@classmethod
def IncrementOpenCount(self):
@@ -3028,25 +3024,31 @@ def Maximize(self):
self.MasterFrame.Maximize()

def _Close(self):
try:
self.TKroot.update()
except:
pass
if not self.NonBlocking:
BuildResults(self, False, self)
if self.TKrootDestroyed:
return None
self.TKrootDestroyed = True
self.RootNeedsDestroying = True
self.Close()
self.__del__()
return None

def Close(self):
if len(Window.active_windows) != 0:
del(Window.active_windows[-1]) # delete current window from active windows
if len(Window.active_windows) != 0:
window = Window.active_windows[-1] # get prior window to change to
print(f'In close, changing to widget {window.master_widget}')
Window.App.set_root_widget(window.master_widget)
else:
self.App.close()
self.App.server.server_starter_instance._alive = False
self.App.server.server_starter_instance._sserver.shutdown()
return

self.App.close()
self.App.server.server_starter_instance._alive = False
self.App.server.server_starter_instance._sserver.shutdown()
if self.TKrootDestroyed:
return
# try:
# self.MasterFrame.Close()
# except:
@@ -3183,23 +3185,28 @@ def remi_thread(self):


class MyApp(remi.App):
def __init__(self,*args):
def __init__(self,*args, userdata2=None):
# self.window = window # type: Window
# print(args[-1])
userdata = args[-1].userdata
self.window = userdata[0] # type: Window
if userdata2 is None:
userdata = args[-1].userdata
self.window = userdata[0] # type: Window
else:
self.window = userdata2
self.window.App = self
super(Window.MyApp, self).__init__(*args)
self.master_widget = None
if userdata2 is None:
super(Window.MyApp, self).__init__(*args)

def main(self, name='world'):
# margin 0px auto allows to center the app to the screen
wid = remi.gui.VBox()
wid.style['justify-content'] = 'flex-start'
wid.style['align-items'] = 'baseline'
self.master_widget = remi.gui.VBox()
self.master_widget.style['justify-content'] = 'flex-start'
self.master_widget.style['align-items'] = 'baseline'
if self.window.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT):
wid.style['background-color'] = self.window.BackgroundColor
self.master_widget.style['background-color'] = self.window.BackgroundColor
try:
PackFormIntoFrame(self.window, wid, self.window)
PackFormIntoFrame(self.window, self.master_widget, self.window)
except:
print('* ERROR PACKING FORM *')
print(traceback.format_exc())
@@ -3208,14 +3215,15 @@ def main(self, name='world'):
tag = remi.gui.Tag(_type='script')
tag.add_child("javascript", """window.onunload=function(e){sendCallback('%s','%s');return "close?";};""" % (
str(id(self)), "on_window_close"))
wid.add_child("onunloadevent", tag)
self.master_widget.add_child("onunloadevent", tag)
self.window.MessageQueue.put('Layout complete') # signal the main code that the layout is all done
return wid # returning the root widget
self.window.master_widget = self.master_widget
return self.master_widget # returning the root widget


def on_window_close(self):
# here you can handle the unload
# print("app closing")
print("app closing")
self.close()
self.server.server_starter_instance._alive = False
self.server.server_starter_instance._sserver.shutdown()
@@ -4821,80 +4829,28 @@ def StartupTK(window:Window):
master = 00000

InitializeResults(window)
# REMI - this call moved to inside of the REMI thread
# PackFormIntoFrame(window, master, window)
# ....................................... DONE creating and laying out window ..........................#
# if MyFlexForm._Size != (None, None):
# master.geometry("%sx%s" % (MyFlexForm._Size[0], MyFlexForm._Size[1]))

# Center in middle of screen
# screen_width = master.winfo_screenwidth() # get window info to move to middle of screen
# screen_height = master.winfo_screenheight()
# if window.Location != (None, None):
# x, y = window.Location
# elif DEFAULT_WINDOW_LOCATION != (None, None):
# x, y = DEFAULT_WINDOW_LOCATION
# else:
# master.update_idletasks() # don't forget to do updates or values are bad
# win_width = master.winfo_width()
# win_height = master.winfo_height()
# x = screen_width / 2 - win_width / 2
# y = screen_height / 2 - win_height / 2
# if y + win_height > screen_height:
# y = screen_height - win_height
# if x + win_width > screen_width:
# x = screen_width - win_width
#
# move_string = '+%i+%i' % (int(x), int(y))
# master.geometry(move_string)
#
# master.update_idletasks() # don't forget


window.thread_id = threading.Thread(target=window.remi_thread, daemon=True)
window.thread_id.daemon = True
window.thread_id.start()
item = window.MessageQueue.get() # Get the layout complete message



# my_flex_form.SetIcon(my_flex_form.WindowIcon)

# root.attributes('-alpha', my_flex_form.AlphaChannel) # Make window visible again

# if my_flex_form.ReturnKeyboardEvents and not my_flex_form.NonBlocking:
# root.bind("<KeyRelease>", my_flex_form._KeyboardCallback)
# root.bind("<MouseWheel>", my_flex_form._MouseWheelCallback)
# elif my_flex_form.ReturnKeyboardEvents:
# root.bind("<Key>", my_flex_form._KeyboardCallback)
# root.bind("<MouseWheel>", my_flex_form._MouseWheelCallback)
if len(Window.active_windows) == 0:
window.thread_id = threading.Thread(target=window.remi_thread, daemon=True)
window.thread_id.daemon = True
window.thread_id.start()
item = window.MessageQueue.get() # Get the layout complete message
Window.active_windows.append(window)
Window.App = window.App
else:
# margin 0px auto allows to center the app to the screen
master_widget = remi.gui.VBox()
master_widget.style['justify-content'] = 'flex-start'
master_widget.style['align-items'] = 'baseline'
if window.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT):
master_widget.style['background-color'] = window.BackgroundColor
PackFormIntoFrame(window, master_widget, window)
window.master_widget = master_widget
Window.active_windows.append(window)
Window.App.set_root_widget(master_widget)

# if my_flex_form.AutoClose:
# duration = DEFAULT_AUTOCLOSE_TIME if my_flex_form.AutoCloseDuration is None else my_flex_form.AutoCloseDuration
# my_flex_form.TKAfterID = root.after(duration * 1000, my_flex_form._AutoCloseAlarmCallback)
#
# if my_flex_form.Timeout != None:
# my_flex_form.TKAfterID = root.after(my_flex_form.Timeout, my_flex_form._TimeoutAlarmCallback)
# if my_flex_form.NonBlocking:
# my_flex_form.TKroot.protocol("WM_DESTROY_WINDOW", my_flex_form.OnClosingCallback)
# my_flex_form.TKroot.protocol("WM_DELETE_WINDOW", my_flex_form.OnClosingCallback)
# else: # it's a blocking form
# print('..... CALLING MainLoop')
# my_flex_form.CurrentlyRunningMainloop = True
# my_flex_form.TKroot.protocol("WM_DESTROY_WINDOW", my_flex_form.OnClosingCallback)
# my_flex_form.TKroot.protocol("WM_DELETE_WINDOW", my_flex_form.OnClosingCallback)
# my_flex_form.TKroot.mainloop()
# my_flex_form.CurrentlyRunningMainloop = False
# my_flex_form.TimerCancelled = True
# print('..... BACK from MainLoop')
# if not my_flex_form.FormRemainedOpen:
# _my_windows.Decrement()
# if my_flex_form.RootNeedsDestroying:
# my_flex_form.TKroot.destroy()
# my_flex_form.RootNeedsDestroying = False
return


# ==============================_GetNumLinesNeeded ==#
# Helper function for determining how to wrap text #
# ===================================================#
@@ -5937,7 +5893,7 @@ def Popup(*args, button_color=None, background_color=None, text_color=None, butt
button, values = window.Read(timeout=0)
else:
button, values = window.Read()
window.Close()
window.Close()
return button


@@ -6469,7 +6425,7 @@ def main():
[Text('PySimpleGUIWeb Welcomes You...', tooltip='text', font=('Comic sans ms', 20),size=(40,1), text_color='red', enable_events=True, key='_PySimpleGUIWeb_')],
[T('Current Time '), Text('Text', key='_TEXT_', font='Arial 18', text_color='black', size=(30,1)), Column(col1, background_color='red')],
[T('Up Time'), Text('Text', key='_TEXT_UPTIME_', font='Arial 18', text_color='black', size=(30,1))],
[Input('Single Line Input', do_not_clear=True, enable_events=True, size=(30, 1), text_color='red')],
[Input('Single Line Input', do_not_clear=True, enable_events=False, size=(30, 1), text_color='red')],
[Multiline('Multiline Input', do_not_clear=True, size=(40, 4), enable_events=True, key='_MULTI_IN_')],
[MultilineOutput('Multiline Output', size=(80, 8), text_color='blue', font='Courier 12', key='_MULTIOUT_')],
[Checkbox('Checkbox 1', enable_events=True, key='_CB1_'), Checkbox('Checkbox 2', default=True, key='_CB2_', enable_events=True)],
@@ -6478,7 +6434,7 @@ def main():
[Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), enable_events =True, size=(10, 3), key='_LIST_')],
[Slider((1, 100), default_value=80, key='_SLIDER_', visible=True, enable_events=True)],
[Spin(values=(1, 2, 3), initial_value='2', size=(4, 1), key='_SPIN_', enable_events=True)],
[OK(), Button('Hidden', visible=False), Button('Values'), Button('Exit', button_color=('white', 'red'))]
[OK(), Button('Hidden', visible=False, key='_HIDDEN_'), Button('Values'), Button('Exit', button_color=('white', 'red')), Button('UnHide')]
]

window = Window('PySimpleGUIWeb Window', font='Arial 18',default_element_size=(12,1), auto_size_buttons=False).Layout(layout)
@@ -6499,6 +6455,10 @@ def main():
window.Element('_MULTIOUT_').Update(str(values), append=True)
elif event != TIMEOUT_KEY:
window.Element('_MULTIOUT_').Update('EVENT: ' + str(event), append=True)
if event == 'UnHide':
print('Unhiding...')
window.Element('_HIDDEN_').Update(visible=True)

window.Close()


0 comments on commit bf2da43

Please sign in to comment.