Multi-window support (experimental release), BringToFront method
This commit is contained in:
parent
70f6002ab9
commit
f3776ff5d4
|
@ -178,6 +178,9 @@ ThisRow = 555666777 # magic number
|
||||||
# DEFAULT_WINDOW_ICON = ''
|
# DEFAULT_WINDOW_ICON = ''
|
||||||
MESSAGE_BOX_LINE_WIDTH = 60
|
MESSAGE_BOX_LINE_WIDTH = 60
|
||||||
|
|
||||||
|
# Key representing a Read timeout
|
||||||
|
TIMEOUT_KEY = '__timeout__'
|
||||||
|
|
||||||
|
|
||||||
# a shameful global variable. This represents the top-level window information. Needed because opening a second window is different than opening the first.
|
# a shameful global variable. This represents the top-level window information. Needed because opening a second window is different than opening the first.
|
||||||
class MyWindows():
|
class MyWindows():
|
||||||
|
@ -380,6 +383,7 @@ class Element():
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = self.DisplayText
|
self.ParentForm.LastButtonClicked = self.DisplayText
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def ReturnKeyHandler(self, event):
|
def ReturnKeyHandler(self, event):
|
||||||
|
@ -397,6 +401,7 @@ class Element():
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def ComboboxSelectHandler(self, event):
|
def ComboboxSelectHandler(self, event):
|
||||||
|
@ -408,6 +413,7 @@ class Element():
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def CheckboxHandler(self):
|
def CheckboxHandler(self):
|
||||||
|
@ -417,6 +423,7 @@ class Element():
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
|
|
||||||
def TabGroupSelectHandler(self, event):
|
def TabGroupSelectHandler(self, event):
|
||||||
|
@ -426,6 +433,7 @@ class Element():
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -883,6 +891,7 @@ class Spin(Element):
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -1225,6 +1234,7 @@ class Button(Element):
|
||||||
self.ParentForm.LastButtonClicked = self.Key
|
self.ParentForm.LastButtonClicked = self.Key
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = self.ButtonText
|
self.ParentForm.LastButtonClicked = self.ButtonText
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick out of loop if read was called
|
self.ParentForm.TKroot.quit() # kick out of loop if read was called
|
||||||
|
|
||||||
# ------- Button Callback ------- #
|
# ------- Button Callback ------- #
|
||||||
|
@ -1300,6 +1310,7 @@ class Button(Element):
|
||||||
self.ParentForm.LastButtonClicked = self.ButtonText
|
self.ParentForm.LastButtonClicked = self.ButtonText
|
||||||
self.ParentForm.FormRemainedOpen = False
|
self.ParentForm.FormRemainedOpen = False
|
||||||
self.ParentForm._Close()
|
self.ParentForm._Close()
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
if self.ParentForm.NonBlocking:
|
if self.ParentForm.NonBlocking:
|
||||||
self.ParentForm.TKroot.destroy()
|
self.ParentForm.TKroot.destroy()
|
||||||
|
@ -1312,6 +1323,7 @@ class Button(Element):
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = self.ButtonText
|
self.ParentForm.LastButtonClicked = self.ButtonText
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop: # if this window is running the mainloop, kick out
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop
|
elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop
|
||||||
self.ParentForm._Close()
|
self.ParentForm._Close()
|
||||||
|
@ -1329,6 +1341,7 @@ class Button(Element):
|
||||||
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
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -1984,6 +1997,7 @@ class Slider(Element):
|
||||||
else:
|
else:
|
||||||
self.ParentForm.LastButtonClicked = ''
|
self.ParentForm.LastButtonClicked = ''
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -2367,6 +2381,7 @@ class Menu(Element):
|
||||||
# print('IN MENU ITEM CALLBACK', item_chosen)
|
# print('IN MENU ITEM CALLBACK', item_chosen)
|
||||||
self.ParentForm.LastButtonClicked = item_chosen
|
self.ParentForm.LastButtonClicked = item_chosen
|
||||||
self.ParentForm.FormRemainedOpen = True
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -2622,6 +2637,7 @@ class Window:
|
||||||
self.NonBlocking = False
|
self.NonBlocking = False
|
||||||
self.TKroot = None
|
self.TKroot = None
|
||||||
self.TKrootDestroyed = False
|
self.TKrootDestroyed = False
|
||||||
|
self.CurrentlyRunningMainloop = False
|
||||||
self.FormRemainedOpen = False
|
self.FormRemainedOpen = False
|
||||||
self.TKAfterID = None
|
self.TKAfterID = None
|
||||||
self.ProgressBarColor = progress_bar_color
|
self.ProgressBarColor = progress_bar_color
|
||||||
|
@ -2753,20 +2769,23 @@ class Window:
|
||||||
def _TimeoutAlarmCallback(self):
|
def _TimeoutAlarmCallback(self):
|
||||||
# first, get the results table built
|
# first, get the results table built
|
||||||
# modify the Results table in the parent FlexForm object
|
# modify the Results table in the parent FlexForm object
|
||||||
|
# print('TIMEOUT CALLBACK')
|
||||||
if self.TimerCancelled:
|
if self.TimerCancelled:
|
||||||
|
# print('** timer was cancelled **')
|
||||||
return
|
return
|
||||||
self.LastButtonClicked = self.TimeoutKey
|
self.LastButtonClicked = self.TimeoutKey
|
||||||
self.FormRemainedOpen = True
|
self.FormRemainedOpen = True
|
||||||
self.TKroot.quit() # kick the users out of the mainloop
|
self.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def Read(self, timeout=None, timeout_key='_timeout_'):
|
def Read(self, timeout=None, timeout_key=TIMEOUT_KEY):
|
||||||
if timeout == 0:
|
if timeout == 0: # timeout of zero runs the old readnonblocking
|
||||||
event, values = self.ReadNonBlocking()
|
event, values = self.ReadNonBlocking()
|
||||||
if event is None:
|
if event is None:
|
||||||
event = timeout_key
|
event = timeout_key
|
||||||
if values is None:
|
if values is None:
|
||||||
event = None
|
event = None
|
||||||
return event, values
|
return event, values # make event None if values was None and return
|
||||||
|
# Read with a timeout
|
||||||
self.Timeout = timeout
|
self.Timeout = timeout
|
||||||
self.TimeoutKey = timeout_key
|
self.TimeoutKey = timeout_key
|
||||||
self.NonBlocking = False
|
self.NonBlocking = False
|
||||||
|
@ -2775,27 +2794,48 @@ class Window:
|
||||||
if not self.Shown:
|
if not self.Shown:
|
||||||
self.Show()
|
self.Show()
|
||||||
else:
|
else:
|
||||||
|
# if already have a button waiting, the return previously built results
|
||||||
|
if self.LastButtonClicked is not None and not self.LastButtonClickedWasRealtime:
|
||||||
|
# print(f'*** Found previous clicked saved {self.LastButtonClicked}')
|
||||||
|
results = BuildResults(self, False, self)
|
||||||
|
self.LastButtonClicked = None
|
||||||
|
return results
|
||||||
InitializeResults(self)
|
InitializeResults(self)
|
||||||
# if the last button clicked was realtime, emulate a read non-blocking
|
# if the last button clicked was realtime, emulate a read non-blocking
|
||||||
# the idea is to quickly return realtime buttons without any blocks until released
|
# the idea is to quickly return realtime buttons without any blocks until released
|
||||||
if self.LastButtonClickedWasRealtime:
|
if self.LastButtonClickedWasRealtime:
|
||||||
|
# print(f'RTime down {self.LastButtonClicked}' )
|
||||||
try:
|
try:
|
||||||
rc = self.TKroot.update()
|
rc = self.TKroot.update()
|
||||||
except:
|
except:
|
||||||
self.TKrootDestroyed = True
|
self.TKrootDestroyed = True
|
||||||
_my_windows.Decrement()
|
_my_windows.Decrement()
|
||||||
|
print('ROOT Destroyed')
|
||||||
results = BuildResults(self, False, self)
|
results = BuildResults(self, False, self)
|
||||||
if results[0] != None and results[0] != timeout_key:
|
if results[0] != None and results[0] != timeout_key:
|
||||||
return results
|
return results
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# print("** REALTIME PROBLEM FOUND **", results)
|
||||||
|
|
||||||
# normal read blocking code....
|
# normal read blocking code....
|
||||||
if timeout != None:
|
if timeout != None:
|
||||||
self.TimerCancelled = False
|
self.TimerCancelled = False
|
||||||
self.TKAfterID = self.TKroot.after(timeout, self._TimeoutAlarmCallback)
|
self.TKAfterID = self.TKroot.after(timeout, self._TimeoutAlarmCallback)
|
||||||
|
self.CurrentlyRunningMainloop = True
|
||||||
|
# print(f'In main {self.Title}')
|
||||||
self.TKroot.mainloop()
|
self.TKroot.mainloop()
|
||||||
|
# print('Out main')
|
||||||
|
self.CurrentlyRunningMainloop = False
|
||||||
|
# if self.LastButtonClicked != TIMEOUT_KEY:
|
||||||
|
# print(f'Window {self.Title} Last button clicked = {self.LastButtonClicked}')
|
||||||
try:
|
try:
|
||||||
self.TKroot.after_cancel(self.TKAfterID)
|
self.TKroot.after_cancel(self.TKAfterID)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
# print('** tkafter cancel failed **')
|
||||||
self.TimerCancelled = True
|
self.TimerCancelled = True
|
||||||
if self.RootNeedsDestroying:
|
if self.RootNeedsDestroying:
|
||||||
self.TKroot.destroy()
|
self.TKroot.destroy()
|
||||||
|
@ -2803,8 +2843,12 @@ class Window:
|
||||||
# if form was closed with X
|
# if form was closed with X
|
||||||
if self.LastButtonClicked is None and self.LastKeyboardEvent is None and self.ReturnValues[0] is None:
|
if self.LastButtonClicked is None and self.LastKeyboardEvent is None and self.ReturnValues[0] is None:
|
||||||
_my_windows.Decrement()
|
_my_windows.Decrement()
|
||||||
|
# Determine return values
|
||||||
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
||||||
return BuildResults(self, False, self)
|
results = BuildResults(self, False, self)
|
||||||
|
if not self.LastButtonClickedWasRealtime:
|
||||||
|
self.LastButtonClicked = None
|
||||||
|
return results
|
||||||
else:
|
else:
|
||||||
return self.ReturnValues
|
return self.ReturnValues
|
||||||
|
|
||||||
|
@ -2820,6 +2864,7 @@ class Window:
|
||||||
except:
|
except:
|
||||||
self.TKrootDestroyed = True
|
self.TKrootDestroyed = True
|
||||||
_my_windows.Decrement()
|
_my_windows.Decrement()
|
||||||
|
# print("read failed")
|
||||||
# return None, None
|
# return None, None
|
||||||
return BuildResults(self, False, self)
|
return BuildResults(self, False, self)
|
||||||
|
|
||||||
|
@ -2928,6 +2973,7 @@ class Window:
|
||||||
self.LastKeyboardEvent = str(event.keysym) + ':' + str(event.keycode)
|
self.LastKeyboardEvent = str(event.keysym) + ':' + str(event.keycode)
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
BuildResults(self, False, self)
|
BuildResults(self, False, self)
|
||||||
|
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
||||||
self.TKroot.quit()
|
self.TKroot.quit()
|
||||||
|
|
||||||
def _MouseWheelCallback(self, event):
|
def _MouseWheelCallback(self, event):
|
||||||
|
@ -2936,6 +2982,7 @@ class Window:
|
||||||
self.LastKeyboardEvent = 'MouseWheel:Down' if event.delta < 0 else 'MouseWheel:Up'
|
self.LastKeyboardEvent = 'MouseWheel:Down' if event.delta < 0 else 'MouseWheel:Up'
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
BuildResults(self, False, self)
|
BuildResults(self, False, self)
|
||||||
|
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
||||||
self.TKroot.quit()
|
self.TKroot.quit()
|
||||||
|
|
||||||
def _Close(self):
|
def _Close(self):
|
||||||
|
@ -3004,6 +3051,12 @@ class Window:
|
||||||
self._AlphaChannel = alpha
|
self._AlphaChannel = alpha
|
||||||
self.TKroot.attributes('-alpha', alpha)
|
self.TKroot.attributes('-alpha', alpha)
|
||||||
|
|
||||||
|
def BringToFront(self):
|
||||||
|
try:
|
||||||
|
self.TKroot.lift()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -4531,7 +4584,9 @@ def StartupTK(my_flex_form):
|
||||||
# my_flex_form.TKroot.protocol("WM_DELETE_WINDOW", my_flex_form.OnClosingCallback())
|
# my_flex_form.TKroot.protocol("WM_DELETE_WINDOW", my_flex_form.OnClosingCallback())
|
||||||
else: # it's a blocking form
|
else: # it's a blocking form
|
||||||
# print('..... CALLING MainLoop')
|
# print('..... CALLING MainLoop')
|
||||||
|
my_flex_form.CurrentlyRunningMainloop = True
|
||||||
my_flex_form.TKroot.mainloop()
|
my_flex_form.TKroot.mainloop()
|
||||||
|
my_flex_form.CurrentlyRunningMainloop = False
|
||||||
my_flex_form.TimerCancelled = True
|
my_flex_form.TimerCancelled = True
|
||||||
# print('..... BACK from MainLoop')
|
# print('..... BACK from MainLoop')
|
||||||
if not my_flex_form.FormRemainedOpen:
|
if not my_flex_form.FormRemainedOpen:
|
||||||
|
|
Loading…
Reference in New Issue