Columns!!
Columns feature, fix for opening multiple windows.
This commit is contained in:
parent
d0ab0c42c5
commit
b757caa18d
507
PySimpleGUI.py
507
PySimpleGUI.py
|
@ -133,6 +133,7 @@ ELEM_TYPE_IMAGE = 30
|
||||||
ELEM_TYPE_INPUT_SLIDER = 10
|
ELEM_TYPE_INPUT_SLIDER = 10
|
||||||
ELEM_TYPE_INPUT_LISTBOX = 11
|
ELEM_TYPE_INPUT_LISTBOX = 11
|
||||||
ELEM_TYPE_OUTPUT = 300
|
ELEM_TYPE_OUTPUT = 300
|
||||||
|
ELEM_TYPE_COLUMN = 555
|
||||||
ELEM_TYPE_PROGRESS_BAR = 200
|
ELEM_TYPE_PROGRESS_BAR = 200
|
||||||
ELEM_TYPE_BLANK = 100
|
ELEM_TYPE_BLANK = 100
|
||||||
|
|
||||||
|
@ -643,6 +644,7 @@ class Button(Element):
|
||||||
# modify the Results table in the parent FlexForm object
|
# modify the Results table in the parent FlexForm object
|
||||||
r,c = self.Position
|
r,c = self.Position
|
||||||
self.ParentForm.LastButtonClicked = self.ButtonText
|
self.ParentForm.LastButtonClicked = self.ButtonText
|
||||||
|
self.ParentForm.FormRemainedOpen = False
|
||||||
# if the form is tabbed, must collect all form's results and destroy all forms
|
# if the form is tabbed, must collect all form's results and destroy all forms
|
||||||
if self.ParentForm.IsTabbedForm:
|
if self.ParentForm.IsTabbedForm:
|
||||||
self.ParentForm.UberParent._Close()
|
self.ParentForm.UberParent._Close()
|
||||||
|
@ -651,12 +653,13 @@ class Button(Element):
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
if self.ParentForm.NonBlocking:
|
if self.ParentForm.NonBlocking:
|
||||||
self.ParentForm.TKroot.destroy()
|
self.ParentForm.TKroot.destroy()
|
||||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
# _my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||||
elif self.BType == BUTTON_TYPE_READ_FORM: # LEAVE THE WINDOW OPEN!! DO NOT CLOSE
|
elif self.BType == BUTTON_TYPE_READ_FORM: # LEAVE THE WINDOW OPEN!! DO NOT CLOSE
|
||||||
# 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
|
||||||
r,c = self.Position
|
r,c = self.Position
|
||||||
self.ParentForm.LastButtonClicked = self.ButtonText
|
self.ParentForm.LastButtonClicked = self.ButtonText
|
||||||
|
self.ParentForm.FormRemainedOpen = True
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -763,6 +766,54 @@ class Slider(Element):
|
||||||
super().__del__()
|
super().__del__()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------- #
|
||||||
|
# Column #
|
||||||
|
# ---------------------------------------------------------------------- #
|
||||||
|
class Column(Element):
|
||||||
|
def __init__(self, layout, background_color = None):
|
||||||
|
self.UseDictionary = False
|
||||||
|
self.ReturnValues = None
|
||||||
|
self.ReturnValuesList = []
|
||||||
|
self.ReturnValuesDictionary = {}
|
||||||
|
self.DictionaryKeyCounter = 0
|
||||||
|
self.ParentWindow = None
|
||||||
|
self.Rows = []
|
||||||
|
self.ParentForm = None
|
||||||
|
self.TKFrame = None
|
||||||
|
|
||||||
|
self.Layout(layout)
|
||||||
|
|
||||||
|
super().__init__(ELEM_TYPE_COLUMN, background_color=background_color)
|
||||||
|
return
|
||||||
|
|
||||||
|
def AddRow(self, *args):
|
||||||
|
''' Parms are a variable number of Elements '''
|
||||||
|
NumRows = len(self.Rows) # number of existing rows is our row number
|
||||||
|
CurrentRowNumber = NumRows # this row's number
|
||||||
|
CurrentRow = [] # start with a blank row and build up
|
||||||
|
# ------------------------- Add the elements to a row ------------------------- #
|
||||||
|
for i, element in enumerate(args): # Loop through list of elements and add them to the row
|
||||||
|
element.Position = (CurrentRowNumber, i)
|
||||||
|
CurrentRow.append(element)
|
||||||
|
if element.Key is not None:
|
||||||
|
self.UseDictionary = True
|
||||||
|
# ------------------------- Append the row to list of Rows ------------------------- #
|
||||||
|
self.Rows.append(CurrentRow)
|
||||||
|
|
||||||
|
def Layout(self, rows):
|
||||||
|
for row in rows:
|
||||||
|
self.AddRow(*row)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
for row in self.Rows:
|
||||||
|
for element in row:
|
||||||
|
element.__del__()
|
||||||
|
try:
|
||||||
|
del(self.TKroot)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
super().__del__()
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------- #
|
# ------------------------------------------------------------------------- #
|
||||||
# FlexForm CLASS #
|
# FlexForm CLASS #
|
||||||
|
@ -791,6 +842,7 @@ class FlexForm:
|
||||||
self.NonBlocking = False
|
self.NonBlocking = False
|
||||||
self.TKroot = None
|
self.TKroot = None
|
||||||
self.TKrootDestroyed = False
|
self.TKrootDestroyed = False
|
||||||
|
self.FormRemainedOpen = False
|
||||||
self.TKAfterID = None
|
self.TKAfterID = None
|
||||||
self.ProgressBarColor = progress_bar_color
|
self.ProgressBarColor = progress_bar_color
|
||||||
self.AutoCloseDuration = auto_close_duration
|
self.AutoCloseDuration = auto_close_duration
|
||||||
|
@ -905,7 +957,7 @@ class FlexForm:
|
||||||
if self.RootNeedsDestroying:
|
if self.RootNeedsDestroying:
|
||||||
self.TKroot.destroy()
|
self.TKroot.destroy()
|
||||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||||
return BuildResults(self, False)
|
return BuildResults(self, False, self)
|
||||||
|
|
||||||
def ReadNonBlocking(self, Message=''):
|
def ReadNonBlocking(self, Message=''):
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
|
@ -919,27 +971,15 @@ class FlexForm:
|
||||||
except:
|
except:
|
||||||
self.TKrootDestroyed = True
|
self.TKrootDestroyed = True
|
||||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||||
return BuildResults(self, False)
|
return BuildResults(self, False, self)
|
||||||
|
|
||||||
# LEGACY version of ReadNonBlocking
|
|
||||||
def Refresh(self, Message=''):
|
|
||||||
if self.TKrootDestroyed:
|
|
||||||
return None, None
|
|
||||||
if Message:
|
|
||||||
print(Message)
|
|
||||||
try:
|
|
||||||
rc = self.TKroot.update()
|
|
||||||
except:
|
|
||||||
self.TKrootDestroyed = True
|
|
||||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
|
||||||
return BuildResults(self, False)
|
|
||||||
|
|
||||||
def _Close(self):
|
def _Close(self):
|
||||||
try:
|
try:
|
||||||
self.TKroot.update()
|
self.TKroot.update()
|
||||||
except: pass
|
except: pass
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
results = BuildResults(self, False)
|
results = BuildResults(self, False, self)
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
return None
|
return None
|
||||||
self.TKrootDestroyed = True
|
self.TKrootDestroyed = True
|
||||||
|
@ -966,10 +1006,10 @@ class FlexForm:
|
||||||
for row in self.Rows:
|
for row in self.Rows:
|
||||||
for element in row:
|
for element in row:
|
||||||
element.__del__()
|
element.__del__()
|
||||||
try:
|
# try:
|
||||||
del(self.TKroot)
|
# del(self.TKroot)
|
||||||
except:
|
# except:
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
# ------------------------------------------------------------------------- #
|
# ------------------------------------------------------------------------- #
|
||||||
# UberForm CLASS #
|
# UberForm CLASS #
|
||||||
|
@ -1093,7 +1133,7 @@ def AddToReturnList(form, value):
|
||||||
#----------------------------------------------------------------------------#
|
#----------------------------------------------------------------------------#
|
||||||
# ------- FUNCTION InitializeResults. Sets up form results matrix --------#
|
# ------- FUNCTION InitializeResults. Sets up form results matrix --------#
|
||||||
def InitializeResults(form):
|
def InitializeResults(form):
|
||||||
BuildResults(form, True)
|
BuildResults(form, True, form)
|
||||||
return
|
return
|
||||||
|
|
||||||
#===== Radio Button RadVar encoding and decoding =====#
|
#===== Radio Button RadVar encoding and decoding =====#
|
||||||
|
@ -1110,42 +1150,64 @@ def EncodeRadioRowCol(row, col):
|
||||||
# ------- FUNCTION BuildResults. Form exiting so build the results to pass back ------- #
|
# ------- FUNCTION BuildResults. Form exiting so build the results to pass back ------- #
|
||||||
# format of return values is
|
# format of return values is
|
||||||
# (Button Pressed, input_values)
|
# (Button Pressed, input_values)
|
||||||
def BuildResults(form, initialize_only):
|
def BuildResults(form, initialize_only, top_level_form):
|
||||||
# Results for elements are:
|
# Results for elements are:
|
||||||
# TEXT - Nothing
|
# TEXT - Nothing
|
||||||
# INPUT - Read value from TK
|
# INPUT - Read value from TK
|
||||||
# Button - Button Text and position as a Tuple
|
# Button - Button Text and position as a Tuple
|
||||||
|
|
||||||
# Get the initialized results so we don't have to rebuild
|
# Get the initialized results so we don't have to rebuild
|
||||||
button_pressed_text = None
|
|
||||||
input_values = []
|
|
||||||
form.DictionaryKeyCounter = 0
|
form.DictionaryKeyCounter = 0
|
||||||
form.ReturnValuesDictionary = {}
|
form.ReturnValuesDictionary = {}
|
||||||
form.ReturnValuesList = []
|
form.ReturnValuesList = []
|
||||||
key_counter = 0
|
BuildResultsForSubform(form, initialize_only, top_level_form)
|
||||||
|
return form.ReturnValues
|
||||||
|
|
||||||
|
def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
|
button_pressed_text = None
|
||||||
for row_num,row in enumerate(form.Rows):
|
for row_num,row in enumerate(form.Rows):
|
||||||
for col_num, element in enumerate(row):
|
for col_num, element in enumerate(row):
|
||||||
|
value = None
|
||||||
|
if element.Type == ELEM_TYPE_COLUMN:
|
||||||
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
|
element.ReturnValuesList = []
|
||||||
|
element.ReturnValuesDictionary = {}
|
||||||
|
BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
|
for item in element.ReturnValuesList:
|
||||||
|
AddToReturnList(top_level_form, item)
|
||||||
|
# for key in element.ReturnValuesDictionary:
|
||||||
|
# top_level_form.ReturnValuesDictionary[key] = element.ReturnValuesDictionary[key]
|
||||||
|
# top_level_form.DictionaryKeyCounter += element.DictionaryKeyCounter
|
||||||
|
if element.UseDictionary:
|
||||||
|
top_level_form.UseDictionary = True
|
||||||
|
if element.ReturnValues[0] is not None: # if a button was clicked
|
||||||
|
button_pressed_text = element.ReturnValues[0]
|
||||||
|
|
||||||
if not initialize_only:
|
if not initialize_only:
|
||||||
if element.Type == ELEM_TYPE_INPUT_TEXT:
|
if element.Type == ELEM_TYPE_INPUT_TEXT:
|
||||||
value=element.TKStringVar.get()
|
value=element.TKStringVar.get()
|
||||||
if not form.NonBlocking and not element.do_not_clear:
|
if not top_level_form.NonBlocking and not element.do_not_clear:
|
||||||
element.TKStringVar.set('')
|
element.TKStringVar.set('')
|
||||||
elif element.Type == ELEM_TYPE_INPUT_CHECKBOX:
|
elif element.Type == ELEM_TYPE_INPUT_CHECKBOX:
|
||||||
value = element.TKIntVar.get()
|
value = element.TKIntVar.get()
|
||||||
|
value = (value != 0)
|
||||||
elif element.Type == ELEM_TYPE_INPUT_RADIO:
|
elif element.Type == ELEM_TYPE_INPUT_RADIO:
|
||||||
RadVar=element.TKIntVar.get()
|
RadVar=element.TKIntVar.get()
|
||||||
this_rowcol = EncodeRadioRowCol(row_num,col_num)
|
this_rowcol = EncodeRadioRowCol(row_num,col_num)
|
||||||
value = RadVar == this_rowcol
|
value = RadVar == this_rowcol
|
||||||
elif element.Type == ELEM_TYPE_BUTTON:
|
elif element.Type == ELEM_TYPE_BUTTON:
|
||||||
if form.LastButtonClicked == element.ButtonText:
|
if top_level_form.LastButtonClicked == element.ButtonText:
|
||||||
button_pressed_text = form.LastButtonClicked
|
button_pressed_text = top_level_form.LastButtonClicked
|
||||||
if element.BType != BUTTON_TYPE_REALTIME: # Do not clear realtime buttons
|
if element.BType != BUTTON_TYPE_REALTIME: # Do not clear realtime buttons
|
||||||
form.LastButtonClicked = None
|
top_level_form.LastButtonClicked = None
|
||||||
elif element.Type == ELEM_TYPE_INPUT_COMBO:
|
elif element.Type == ELEM_TYPE_INPUT_COMBO:
|
||||||
value=element.TKStringVar.get()
|
value=element.TKStringVar.get()
|
||||||
elif element.Type == ELEM_TYPE_INPUT_LISTBOX:
|
elif element.Type == ELEM_TYPE_INPUT_LISTBOX:
|
||||||
|
try:
|
||||||
items=element.TKListbox.curselection()
|
items=element.TKListbox.curselection()
|
||||||
value = [element.Values[int(item)] for item in items]
|
value = [element.Values[int(item)] for item in items]
|
||||||
|
except:
|
||||||
|
value = ''
|
||||||
elif element.Type == ELEM_TYPE_INPUT_SPIN:
|
elif element.Type == ELEM_TYPE_INPUT_SPIN:
|
||||||
try:
|
try:
|
||||||
value=element.TKStringVar.get()
|
value=element.TKStringVar.get()
|
||||||
|
@ -1159,17 +1221,18 @@ def BuildResults(form, initialize_only):
|
||||||
elif element.Type == ELEM_TYPE_INPUT_MULTILINE:
|
elif element.Type == ELEM_TYPE_INPUT_MULTILINE:
|
||||||
try:
|
try:
|
||||||
value=element.TKText.get(1.0, tk.END)
|
value=element.TKText.get(1.0, tk.END)
|
||||||
if not form.NonBlocking and not element.do_not_clear:
|
if not top_level_form.NonBlocking and not element.do_not_clear:
|
||||||
element.TKText.delete('1.0', tk.END)
|
element.TKText.delete('1.0', tk.END)
|
||||||
except:
|
except:
|
||||||
value = None
|
value = None
|
||||||
else:
|
else:
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
# if an input type element, update the results
|
# if an input type element, update the results
|
||||||
if element.Type != ELEM_TYPE_BUTTON and element.Type != ELEM_TYPE_TEXT and element.Type != ELEM_TYPE_IMAGE and\
|
if element.Type != ELEM_TYPE_BUTTON and element.Type != ELEM_TYPE_TEXT and element.Type != ELEM_TYPE_IMAGE and\
|
||||||
element.Type != ELEM_TYPE_OUTPUT and element.Type != ELEM_TYPE_PROGRESS_BAR:
|
element.Type != ELEM_TYPE_OUTPUT and element.Type != ELEM_TYPE_PROGRESS_BAR and element.Type!= ELEM_TYPE_COLUMN:
|
||||||
AddToReturnList(form, value)
|
AddToReturnList(form, value)
|
||||||
AddToReturnDictionary(form, element, value)
|
AddToReturnDictionary(top_level_form, element, value)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
form.ReturnValuesDictionary.pop(None, None) # clean up dictionary include None was included
|
form.ReturnValuesDictionary.pop(None, None) # clean up dictionary include None was included
|
||||||
|
@ -1186,7 +1249,379 @@ def BuildResults(form, initialize_only):
|
||||||
# ------------------------------------------------------------------------------------------------------------------ #
|
# ------------------------------------------------------------------------------------------------------------------ #
|
||||||
# ===================================== TK CODE STARTS HERE ====================================================== #
|
# ===================================== TK CODE STARTS HERE ====================================================== #
|
||||||
# ------------------------------------------------------------------------------------------------------------------ #
|
# ------------------------------------------------------------------------------------------------------------------ #
|
||||||
|
|
||||||
|
def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
||||||
|
def CharWidthInPixels():
|
||||||
|
return tkinter.font.Font().measure('A') # single character width
|
||||||
|
# only set title on non-tabbed forms
|
||||||
|
border_depth = toplevel_form.BorderDepth if toplevel_form.BorderDepth is not None else DEFAULT_BORDER_WIDTH
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# **************** Use FlexForm to build the tkinter window ********** ----- #
|
||||||
|
# Building is done row by row. #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
focus_set = False
|
||||||
|
######################### LOOP THROUGH ROWS #########################
|
||||||
|
# *********** ------- Loop through ROWS ------- ***********#
|
||||||
|
for row_num, flex_row in enumerate(form.Rows):
|
||||||
|
######################### LOOP THROUGH ELEMENTS ON ROW #########################
|
||||||
|
# *********** ------- Loop through ELEMENTS ------- ***********#
|
||||||
|
# *********** Make TK Row ***********#
|
||||||
|
tk_row_frame = tk.Frame(containing_frame)
|
||||||
|
for col_num, element in enumerate(flex_row):
|
||||||
|
element.ParentForm = toplevel_form # save the button's parent form object
|
||||||
|
if toplevel_form.Font and (element.Font == DEFAULT_FONT or not element.Font):
|
||||||
|
font = toplevel_form.Font
|
||||||
|
elif element.Font is not None:
|
||||||
|
font = element.Font
|
||||||
|
else:
|
||||||
|
font = DEFAULT_FONT
|
||||||
|
# ------- Determine Auto-Size setting on a cascading basis ------- #
|
||||||
|
if element.AutoSizeText is not None: # if element overide
|
||||||
|
auto_size_text = element.AutoSizeText
|
||||||
|
elif toplevel_form.AutoSizeText is not None: # if form override
|
||||||
|
auto_size_text = toplevel_form.AutoSizeText
|
||||||
|
else:
|
||||||
|
auto_size_text = DEFAULT_AUTOSIZE_TEXT
|
||||||
|
# Determine Element size
|
||||||
|
element_size = element.Size
|
||||||
|
if (element_size == (None, None)): # user did not specify a size
|
||||||
|
element_size = toplevel_form.DefaultElementSize
|
||||||
|
else: auto_size_text = False # if user has specified a size then it shouldn't autosize
|
||||||
|
# Apply scaling... Element scaling is higher priority than form level
|
||||||
|
if element.Scale != (None, None):
|
||||||
|
element_size = (int(element_size[0] * element.Scale[0]), int(element_size[1] * element.Scale[1]))
|
||||||
|
elif toplevel_form.Scale != (None, None):
|
||||||
|
element_size = (int(element_size[0] * toplevel_form.Scale[0]), int(element_size[1] * toplevel_form.Scale[1]))
|
||||||
|
# Set foreground color
|
||||||
|
text_color = element.TextColor
|
||||||
|
element_type = element.Type
|
||||||
|
# ------------------------- COLUMN element ------------------------- #
|
||||||
|
if element_type == ELEM_TYPE_COLUMN:
|
||||||
|
col_frame = tk.Frame(tk_row_frame)
|
||||||
|
PackFormIntoFrame(element, col_frame, toplevel_form)
|
||||||
|
col_frame.pack(side=tk.LEFT)
|
||||||
|
if element.BackgroundColor is not None:
|
||||||
|
col_frame.configure(background=element.BackgroundColor, highlightbackground=element.BackgroundColor, highlightcolor=element.BackgroundColor)
|
||||||
|
# ------------------------- TEXT element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_TEXT:
|
||||||
|
display_text = element.DisplayText # text to display
|
||||||
|
if auto_size_text is False:
|
||||||
|
width, height=element_size
|
||||||
|
else:
|
||||||
|
lines = display_text.split('\n')
|
||||||
|
max_line_len = max([len(l) for l in lines])
|
||||||
|
num_lines = len(lines)
|
||||||
|
if max_line_len > element_size[0]: # if text exceeds element size, the will have to wrap
|
||||||
|
width = element_size[0]
|
||||||
|
else:
|
||||||
|
width=max_line_len
|
||||||
|
height=num_lines
|
||||||
|
# ---===--- LABEL widget create and place --- #
|
||||||
|
stringvar = tk.StringVar()
|
||||||
|
element.TKStringVar = stringvar
|
||||||
|
stringvar.set(display_text)
|
||||||
|
if auto_size_text:
|
||||||
|
width = 0
|
||||||
|
justify = tk.LEFT if element.Justification == 'left' else tk.CENTER if element.Justification == 'center' else tk.RIGHT
|
||||||
|
anchor = tk.NW if element.Justification == 'left' else tk.N if element.Justification == 'center' else tk.NE
|
||||||
|
tktext_label = tk.Label(tk_row_frame, textvariable=stringvar, width=width, height=height, justify=justify, bd=border_depth)
|
||||||
|
# tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth)
|
||||||
|
# Set wrap-length for text (in PIXELS) == PAIN IN THE ASS
|
||||||
|
wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels
|
||||||
|
tktext_label.configure(anchor=anchor, font=font, wraplen=wraplen*2 ) # set wrap to width of widget
|
||||||
|
if element.BackgroundColor is not None:
|
||||||
|
tktext_label.configure(background=element.BackgroundColor)
|
||||||
|
if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None:
|
||||||
|
tktext_label.configure(fg=element.TextColor)
|
||||||
|
tktext_label.pack(side=tk.LEFT)
|
||||||
|
# ------------------------- BUTTON element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_BUTTON:
|
||||||
|
element.Location = (row_num, col_num)
|
||||||
|
btext = element.ButtonText
|
||||||
|
btype = element.BType
|
||||||
|
if element.AutoSizeButton is not None:
|
||||||
|
auto_size = element.AutoSizeButton
|
||||||
|
else: auto_size = toplevel_form.AutoSizeButtons
|
||||||
|
if auto_size is False: width=element_size[0]
|
||||||
|
else: width = 0
|
||||||
|
height=element_size[1]
|
||||||
|
lines = btext.split('\n')
|
||||||
|
max_line_len = max([len(l) for l in lines])
|
||||||
|
num_lines = len(lines)
|
||||||
|
if element.ButtonColor != (None, None)and element.ButtonColor != DEFAULT_BUTTON_COLOR:
|
||||||
|
bc = element.ButtonColor
|
||||||
|
elif toplevel_form.ButtonColor != (None, None) and toplevel_form.ButtonColor != DEFAULT_BUTTON_COLOR:
|
||||||
|
bc = toplevel_form.ButtonColor
|
||||||
|
else:
|
||||||
|
bc = DEFAULT_BUTTON_COLOR
|
||||||
|
border_depth = element.BorderWidth
|
||||||
|
if btype != BUTTON_TYPE_REALTIME:
|
||||||
|
tkbutton = tk.Button(tk_row_frame, text=btext, width=width, height=height,command=element.ButtonCallBack, justify=tk.LEFT, bd=border_depth)
|
||||||
|
else:
|
||||||
|
tkbutton = tk.Button(tk_row_frame, text=btext, width=width, height=height, justify=tk.LEFT, bd=border_depth)
|
||||||
|
tkbutton.bind('<ButtonRelease-1>', element.ButtonReleaseCallBack)
|
||||||
|
tkbutton.bind('<ButtonPress-1>', element.ButtonPressCallBack)
|
||||||
|
if bc != (None, None) and bc != COLOR_SYSTEM_DEFAULT:
|
||||||
|
tkbutton.config(foreground=bc[0], background=bc[1])
|
||||||
|
element.TKButton = tkbutton # not used yet but save the TK button in case
|
||||||
|
wraplen = tkbutton.winfo_reqwidth() # width of widget in Pixels
|
||||||
|
if element.ImageFilename: # if button has an image on it
|
||||||
|
print('Button Image Filename being placed', element.ImageFilename)
|
||||||
|
photo = tk.PhotoImage(file=element.ImageFilename)
|
||||||
|
print('PhotoImage object', ObjToString(photo))
|
||||||
|
if element.ImageSize != (None, None):
|
||||||
|
width, height = element.ImageSize
|
||||||
|
if element.ImageSubsample:
|
||||||
|
photo = photo.subsample(element.ImageSubsample)
|
||||||
|
else:
|
||||||
|
width, height = photo.width(), photo.height()
|
||||||
|
tkbutton.config(image=photo, width=width, height=height)
|
||||||
|
tkbutton.image = photo
|
||||||
|
tkbutton.configure(wraplength=wraplen+10, font=font) # set wrap to width of widget
|
||||||
|
tkbutton.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
if element.Focus is True or (toplevel_form.UseDefaultFocus and not focus_set):
|
||||||
|
focus_set = True
|
||||||
|
element.TKButton.bind('<Return>', element.ReturnKeyHandler)
|
||||||
|
element.TKButton.focus_set()
|
||||||
|
toplevel_form.TKroot.focus_force()
|
||||||
|
# ------------------------- INPUT (Single Line) element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_TEXT:
|
||||||
|
default_text = element.DefaultText
|
||||||
|
element.TKStringVar = tk.StringVar()
|
||||||
|
element.TKStringVar.set(default_text)
|
||||||
|
show = element.PasswordCharacter if element.PasswordCharacter else ""
|
||||||
|
element.TKEntry = tk.Entry(tk_row_frame, width=element_size[0], textvariable=element.TKStringVar, bd=border_depth, font=font, show=show)
|
||||||
|
element.TKEntry.bind('<Return>', element.ReturnKeyHandler)
|
||||||
|
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKEntry.configure(background=element.BackgroundColor)
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKEntry.configure(fg=text_color)
|
||||||
|
element.TKEntry.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
if element.Focus is True or (toplevel_form.UseDefaultFocus and not focus_set):
|
||||||
|
focus_set = True
|
||||||
|
element.TKEntry.focus_set()
|
||||||
|
# ------------------------- COMBO BOX (Drop Down) element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_COMBO:
|
||||||
|
max_line_len = max([len(str(l)) for l in element.Values])
|
||||||
|
if auto_size_text is False: width=element_size[0]
|
||||||
|
else: width = max_line_len
|
||||||
|
element.TKStringVar = tk.StringVar()
|
||||||
|
if element.BackgroundColor and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||||
|
combostyle = ttk.Style()
|
||||||
|
try:
|
||||||
|
combostyle.theme_create('combostyle',
|
||||||
|
settings={'TCombobox':
|
||||||
|
{'configure':
|
||||||
|
{'selectbackground': element.BackgroundColor,
|
||||||
|
'fieldbackground': element.BackgroundColor,
|
||||||
|
'foreground': text_color,
|
||||||
|
'background': element.BackgroundColor}
|
||||||
|
}})
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
combostyle.theme_settings('combostyle',
|
||||||
|
settings={'TCombobox':
|
||||||
|
{'configure':
|
||||||
|
{'selectbackground': element.BackgroundColor,
|
||||||
|
'fieldbackground': element.BackgroundColor,
|
||||||
|
'foreground': text_color,
|
||||||
|
'background': element.BackgroundColor}
|
||||||
|
}})
|
||||||
|
except: pass
|
||||||
|
# ATTENTION: this applies the new style 'combostyle' to all ttk.Combobox
|
||||||
|
combostyle.theme_use('combostyle')
|
||||||
|
element.TKCombo = ttk.Combobox(tk_row_frame, width=width, textvariable=element.TKStringVar,font=font )
|
||||||
|
# element.TKCombo['state']='readonly'
|
||||||
|
element.TKCombo['values'] = element.Values
|
||||||
|
# if element.BackgroundColor is not None:
|
||||||
|
# element.TKCombo.configure(background=element.BackgroundColor)
|
||||||
|
element.TKCombo.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
element.TKCombo.current(0)
|
||||||
|
# ------------------------- LISTBOX element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_LISTBOX:
|
||||||
|
max_line_len = max([len(str(l)) for l in element.Values])
|
||||||
|
if auto_size_text is False: width=element_size[0]
|
||||||
|
else: width = max_line_len
|
||||||
|
|
||||||
|
element.TKStringVar = tk.StringVar()
|
||||||
|
element.TKListbox= tk.Listbox(tk_row_frame, height=element_size[1], width=width, selectmode=element.SelectMode, font=font)
|
||||||
|
for item in element.Values:
|
||||||
|
element.TKListbox.insert(tk.END, item)
|
||||||
|
element.TKListbox.selection_set(0,0)
|
||||||
|
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKListbox.configure(background=element.BackgroundColor)
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKListbox.configure(fg=text_color)
|
||||||
|
# vsb = tk.Scrollbar(tk_row_frame, orient="vertical", command=element.TKListbox.yview)
|
||||||
|
# element.TKListbox.configure(yscrollcommand=vsb.set)
|
||||||
|
element.TKListbox.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
# vsb.pack(side=tk.LEFT, fill='y')
|
||||||
|
# ------------------------- INPUT MULTI LINE element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_MULTILINE:
|
||||||
|
default_text = element.DefaultText
|
||||||
|
width, height = element_size
|
||||||
|
element.TKText = tk.scrolledtext.ScrolledText(tk_row_frame, width=width, height=height, wrap='word', bd=border_depth,font=font)
|
||||||
|
element.TKText.insert(1.0, default_text) # set the default text
|
||||||
|
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKText.configure(background=element.BackgroundColor)
|
||||||
|
element.TKText.vbar.config(troughcolor=DEFAULT_SCROLLBAR_COLOR)
|
||||||
|
element.TKText.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
if element.EnterSubmits:
|
||||||
|
element.TKText.bind('<Return>', element.ReturnKeyHandler)
|
||||||
|
if element.Focus is True or (toplevel_form.UseDefaultFocus and not focus_set):
|
||||||
|
focus_set = True
|
||||||
|
element.TKText.focus_set()
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKText.configure(fg=text_color)
|
||||||
|
# ------------------------- INPUT CHECKBOX element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_CHECKBOX:
|
||||||
|
width = 0 if auto_size_text else element_size[0]
|
||||||
|
default_value = element.InitialState
|
||||||
|
element.TKIntVar = tk.IntVar()
|
||||||
|
element.TKIntVar.set(default_value if default_value is not None else 0)
|
||||||
|
element.TKCheckbutton = tk.Checkbutton(tk_row_frame, anchor=tk.NW, text=element.Text, width=width, variable=element.TKIntVar, bd=border_depth, font=font)
|
||||||
|
if default_value is None:
|
||||||
|
element.TKCheckbutton.configure(state='disable')
|
||||||
|
if element.BackgroundColor is not None:
|
||||||
|
element.TKCheckbutton.configure(background=element.BackgroundColor)
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKCheckbutton.configure(fg=text_color)
|
||||||
|
element.TKCheckbutton.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
# ------------------------- PROGRESS BAR element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_PROGRESS_BAR:
|
||||||
|
# save this form because it must be 'updated' (refreshed) solely for the purpose of updating bar
|
||||||
|
width = element_size[0]
|
||||||
|
fnt = tkinter.font.Font()
|
||||||
|
char_width = fnt.measure('A') # single character width
|
||||||
|
progress_length = width*char_width
|
||||||
|
progress_width = element_size[1]
|
||||||
|
direction = element.Orientation
|
||||||
|
if element.BarColor != (None, None): # if element has a bar color, use it
|
||||||
|
bar_color = element.BarColor
|
||||||
|
else:
|
||||||
|
bar_color = DEFAULT_PROGRESS_BAR_COLOR
|
||||||
|
element.TKProgressBar = TKProgressBar(tk_row_frame, element.MaxValue, progress_length, progress_width, orientation=direction, BarColor=bar_color, border_width=element.BorderWidth, relief=element.Relief, style=element.BarStyle )
|
||||||
|
# element.TKProgressBar = TKProgressBar(tk_row_frame, element.MaxValue, progress_length, progress_width, orientation=direction, BarColor=bar_color, border_width=element.BorderWidth, relief=element.Relief)
|
||||||
|
element.TKProgressBar.TKProgressBarForReal.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
# ------------------------- INPUT RADIO BUTTON element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_RADIO:
|
||||||
|
width = 0 if auto_size_text else element_size[0]
|
||||||
|
default_value = element.InitialState
|
||||||
|
ID = element.GroupID
|
||||||
|
# see if ID has already been placed
|
||||||
|
value = EncodeRadioRowCol(row_num, col_num) # value to set intvar to if this radio is selected
|
||||||
|
if ID in toplevel_form.RadioDict:
|
||||||
|
RadVar = toplevel_form.RadioDict[ID]
|
||||||
|
else:
|
||||||
|
RadVar = tk.IntVar()
|
||||||
|
toplevel_form.RadioDict[ID] = RadVar
|
||||||
|
element.TKIntVar = RadVar # store the RadVar in Radio object
|
||||||
|
if default_value: # if this radio is the one selected, set RadVar to match
|
||||||
|
element.TKIntVar.set(value)
|
||||||
|
element.TKRadio = tk.Radiobutton(tk_row_frame, anchor=tk.NW, text=element.Text, width=width,
|
||||||
|
variable=element.TKIntVar, value=value, bd=border_depth, font=font)
|
||||||
|
if element.BackgroundColor is not None:
|
||||||
|
element.TKRadio.configure(background=element.BackgroundColor)
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKRadio.configure(fg=text_color)
|
||||||
|
element.TKRadio.pack(side=tk.LEFT, padx=element.Pad[0],pady=element.Pad[1])
|
||||||
|
# ------------------------- INPUT SPIN Box element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_SPIN:
|
||||||
|
width, height = element_size
|
||||||
|
width = 0 if auto_size_text else element_size[0]
|
||||||
|
element.TKStringVar = tk.StringVar()
|
||||||
|
element.TKSpinBox = tk.Spinbox(tk_row_frame, values=element.Values, textvariable=element.TKStringVar, width=width, bd=border_depth)
|
||||||
|
element.TKStringVar.set(element.DefaultValue)
|
||||||
|
element.TKSpinBox.configure(font=font) # set wrap to width of widget
|
||||||
|
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKSpinBox.configure(background=element.BackgroundColor)
|
||||||
|
element.TKSpinBox.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
element.TKSpinBox.configure(fg=text_color)
|
||||||
|
# ------------------------- OUTPUT element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_OUTPUT:
|
||||||
|
width, height = element_size
|
||||||
|
element.TKOut = TKOutput(tk_row_frame, width=width, height=height, bd=border_depth, background_color=element.BackgroundColor, text_color=text_color)
|
||||||
|
element.TKOut.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||||
|
# ------------------------- IMAGE Box element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_IMAGE:
|
||||||
|
photo = tk.PhotoImage(file=element.Filename)
|
||||||
|
if element_size == (None, None) or element_size == None or element_size == toplevel_form.DefaultElementSize:
|
||||||
|
width, height = photo.width(), photo.height()
|
||||||
|
else:
|
||||||
|
width, height = element_size
|
||||||
|
tktext_label = tk.Label(tk_row_frame, image=photo, width=width, height=height, bd=border_depth)
|
||||||
|
tktext_label.image = photo
|
||||||
|
# tktext_label.configure(anchor=tk.NW, image=photo)
|
||||||
|
tktext_label.pack(side=tk.LEFT)
|
||||||
|
# ------------------------- SLIDER Box element ------------------------- #
|
||||||
|
elif element_type == ELEM_TYPE_INPUT_SLIDER:
|
||||||
|
slider_length = element_size[0] * CharWidthInPixels()
|
||||||
|
slider_width = element_size[1]
|
||||||
|
element.TKIntVar = tk.IntVar()
|
||||||
|
element.TKIntVar.set(element.DefaultValue)
|
||||||
|
if element.Orientation[0] == 'v':
|
||||||
|
range_from = element.Range[1]
|
||||||
|
range_to = element.Range[0]
|
||||||
|
slider_length += DEFAULT_MARGINS[1]*(element_size[0]*2) # add in the padding
|
||||||
|
else:
|
||||||
|
range_from = element.Range[0]
|
||||||
|
range_to = element.Range[1]
|
||||||
|
tkscale = tk.Scale(tk_row_frame, orient=element.Orientation, variable=element.TKIntVar, from_=range_from, to_=range_to, length=slider_length, width=slider_width , bd=element.BorderWidth, relief=element.Relief, font=font)
|
||||||
|
# tktext_label.configure(anchor=tk.NW, image=photo)
|
||||||
|
if element.BackgroundColor is not None:
|
||||||
|
tkscale.configure(background=element.BackgroundColor)
|
||||||
|
tkscale.config(troughcolor=DEFAULT_SCROLLBAR_COLOR)
|
||||||
|
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||||
|
tkscale.configure(fg=text_color)
|
||||||
|
tkscale.pack(side=tk.LEFT)
|
||||||
|
#............................DONE WITH ROW pack the row of widgets ..........................#
|
||||||
|
# done with row, pack the row of widgets
|
||||||
|
tk_row_frame.grid(row=row_num+2, sticky=tk.NW, padx=DEFAULT_MARGINS[0])
|
||||||
|
|
||||||
|
if form.BackgroundColor is not None:
|
||||||
|
tk_row_frame.configure(background=form.BackgroundColor)
|
||||||
|
if not toplevel_form.IsTabbedForm:
|
||||||
|
toplevel_form.TKroot.configure(padx=DEFAULT_MARGINS[0], pady=DEFAULT_MARGINS[1])
|
||||||
|
else: toplevel_form.ParentWindow.configure(padx=DEFAULT_MARGINS[0], pady=DEFAULT_MARGINS[1])
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def ConvertFlexToTK(MyFlexForm):
|
def ConvertFlexToTK(MyFlexForm):
|
||||||
|
master = MyFlexForm.TKroot
|
||||||
|
# only set title on non-tabbed forms
|
||||||
|
if not MyFlexForm.IsTabbedForm:
|
||||||
|
master.title(MyFlexForm.Title)
|
||||||
|
InitializeResults(MyFlexForm)
|
||||||
|
PackFormIntoFrame(MyFlexForm, master, MyFlexForm)
|
||||||
|
#....................................... DONE creating and laying out window ..........................#
|
||||||
|
if MyFlexForm.IsTabbedForm:
|
||||||
|
master = MyFlexForm.ParentWindow
|
||||||
|
master.attributes('-alpha', 0) # hide window while getting info and moving
|
||||||
|
screen_width = master.winfo_screenwidth() # get window info to move to middle of screen
|
||||||
|
screen_height = master.winfo_screenheight()
|
||||||
|
if MyFlexForm.Location != (None, None):
|
||||||
|
x,y = MyFlexForm.Location
|
||||||
|
elif DEFAULT_WINDOW_LOCATION != (None, None):
|
||||||
|
x,y = DEFAULT_WINDOW_LOCATION
|
||||||
|
else:
|
||||||
|
master.update_idletasks() # don't forget
|
||||||
|
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.attributes('-alpha', 255) # Make window visible again
|
||||||
|
master.update_idletasks() # don't forget
|
||||||
|
return
|
||||||
|
|
||||||
|
def ConvertFlexToTKOld(MyFlexForm):
|
||||||
def CharWidthInPixels():
|
def CharWidthInPixels():
|
||||||
return tkinter.font.Font().measure('A') # single character width
|
return tkinter.font.Font().measure('A') # single character width
|
||||||
master = MyFlexForm.TKroot
|
master = MyFlexForm.TKroot
|
||||||
|
@ -1542,6 +1977,7 @@ def ConvertFlexToTK(MyFlexForm):
|
||||||
|
|
||||||
# ----====----====----====----====----==== STARTUP TK ====----====----====----====----====----#
|
# ----====----====----====----====----==== STARTUP TK ====----====----====----====----====----#
|
||||||
def ShowTabbedForm(title, *args, auto_close=False, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, fav_icon=DEFAULT_WINDOW_ICON):
|
def ShowTabbedForm(title, *args, auto_close=False, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, fav_icon=DEFAULT_WINDOW_ICON):
|
||||||
|
# takes as input (form, rows, tab name) for each tab
|
||||||
global _my_windows
|
global _my_windows
|
||||||
|
|
||||||
uber = UberForm()
|
uber = UberForm()
|
||||||
|
@ -1617,9 +2053,9 @@ def StartupTK(my_flex_form):
|
||||||
my_flex_form.TKAfterID = root.after(duration * 1000, my_flex_form._AutoCloseAlarmCallback)
|
my_flex_form.TKAfterID = root.after(duration * 1000, my_flex_form._AutoCloseAlarmCallback)
|
||||||
if my_flex_form.NonBlocking:
|
if my_flex_form.NonBlocking:
|
||||||
my_flex_form.TKroot.protocol("WM_WINDOW_DESTROYED", my_flex_form.OnClosingCallback())
|
my_flex_form.TKroot.protocol("WM_WINDOW_DESTROYED", my_flex_form.OnClosingCallback())
|
||||||
pass
|
|
||||||
else: # it's a blocking form
|
else: # it's a blocking form
|
||||||
my_flex_form.TKroot.mainloop()
|
my_flex_form.TKroot.mainloop()
|
||||||
|
if not my_flex_form.FormRemainedOpen:
|
||||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||||
if my_flex_form.RootNeedsDestroying:
|
if my_flex_form.RootNeedsDestroying:
|
||||||
my_flex_form.TKroot.destroy()
|
my_flex_form.TKroot.destroy()
|
||||||
|
@ -1673,7 +2109,8 @@ def MsgBox(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, a
|
||||||
local_line_width = line_width
|
local_line_width = line_width
|
||||||
else:
|
else:
|
||||||
local_line_width = MESSAGE_BOX_LINE_WIDTH
|
local_line_width = MESSAGE_BOX_LINE_WIDTH
|
||||||
with FlexForm(args_to_print[0], auto_size_text=True, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font) as form:
|
title = args_to_print[0] if args_to_print[0] is not None else 'None'
|
||||||
|
with FlexForm(title, auto_size_text=True, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font) as form:
|
||||||
max_line_total, total_lines = 0,0
|
max_line_total, total_lines = 0,0
|
||||||
for message in args_to_print:
|
for message in args_to_print:
|
||||||
# fancy code to check if string and convert if not is not need. Just always convert to string :-)
|
# fancy code to check if string and convert if not is not need. Just always convert to string :-)
|
||||||
|
@ -2060,7 +2497,7 @@ class DebugWin():
|
||||||
# print(1, 2, 3, sep='-')
|
# print(1, 2, 3, sep='-')
|
||||||
# if end is None:
|
# if end is None:
|
||||||
# print("")
|
# print("")
|
||||||
self.form.Refresh()
|
self.form.ReadNonBlocking()
|
||||||
|
|
||||||
def Close(self):
|
def Close(self):
|
||||||
self.form.CloseNonBlockingForm()
|
self.form.CloseNonBlockingForm()
|
||||||
|
|
Loading…
Reference in New Issue