class BaseApplication(): def __init__(self, master, file, title): self.multi_marker = lambda x: ','.join(['?'] * x) self.__builder = Builder() self.__master = master self.__builder.add_from_file(file) self.__master.title(title) self.__master.resizable(False, False) self.__master.wm_attributes("-topmost", 1) self.__master.geometry("+{}+0".format( int(self.__master.winfo_screenwidth() / 2 + 200))) self.cursor = con.cursor() self.user_id = self.cursor.execute( f'SELECT UserID FROM tblUsers WHERE EmployeeDesktopName= ?', (os.getlogin(), )).fetchone() self.groups = self.cursor.execute( f'SELECT Sub_group FROM tblMain WHERE Users= ?', (self.user_id, )).fetchall() @property def master(self): return self.__master @property def builder(self): return self.__builder def get_builder_object(self, name): return self.__builder.get_object(name, self.__master)
def __init__(self): super(UI2Code, self).__init__() self.buffer = None self.as_class = False self._code_imports = OrderedDict() self._tkvariables = {} self._tkimages = {} self._callbacks = {} self._import_ttk = True; self._code = [] self.uidefinition = None self._builder = Builder() self._options = {}
def __init__(self): super(UI2Code, self).__init__() self.buffer = None self.as_class = False self._code_imports = OrderedDict() self._tkvariables = {} self._tkimages = {} self._callbacks = {} self._import_ttk = True self._code = [] # Used for preventing duplicate grid row/column configure lines from # ending up in the generated code. self._unique_grid_properties = [] self.uidefinition = None self._builder = Builder() self._options = {}
class UI2Code(Builder): def __init__(self): super(UI2Code, self).__init__() self.buffer = None self.as_class = False self._code_imports = OrderedDict() self._tkvariables = {} self._tkimages = {} self._callbacks = {} self._import_ttk = True; self._code = [] self.uidefinition = None self._builder = Builder() self._options = {} def _process_options(self, kw): kwdef = { 'as_class': True, 'tabspaces': 8 } kwdef.update(kw) self._options = kwdef self.as_class = self._options['as_class'] tabspaces = self._options['tabspaces'] def _process_results(self, target): tabspaces = self._options['tabspaces'] code = [] for line in self._code: line = '{0}{1}\n'.format(' ' * tabspaces, line) code.append(line) code = ''.join(code) code_imports = self._process_imports() code_imports = '\n'.join(code_imports) code_callbacks = self._process_callbacks() code_callbacks = '\n'.join(code_callbacks) code = ''.join(code) cc = { 'imports': code_imports, target: code, 'callbacks': code_callbacks, } return cc def _toplevel_or_tk(self, target): wmeta = self.uidefinition.get_widget(target) if wmeta.classname == 'tk.Toplevel': wmeta.classname = 'pygubudesigner.ToplevelOrTk' self.uidefinition.replace_widget(target, wmeta) def generate(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = WidgetMeta('','master') builder = BuilderObject(self, mastermeta) self._toplevel_or_tk(target) wmeta = self.uidefinition.get_widget(target) if wmeta is not None: self._code_realize(builder, wmeta) return self._process_results(target) def generate_widget_class(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = wmeta = self.uidefinition.get_widget(target) builder = bmaster = BuilderObject(self, mastermeta) if wmeta is not None: originalid = wmeta.identifier wmeta.identifier = 'self' if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() for childmeta in \ self.uidefinition.widget_children(target): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) return self._process_results(target) def code_classname_for(self, bobject): wmeta = bobject.wmeta cname = None if bobject.class_ is not None: if wmeta.classname == 'pygubudesigner.ToplevelOrTk': cname = 'tk.Toplevel' elif wmeta.classname.startswith('tk.'): cname = wmeta.classname elif wmeta.classname.startswith('ttk.'): self._import_ttk = True; cname = wmeta.classname else: module = bobject.class_.__module__ cname = bobject.class_.__name__ if module not in self._code_imports: self._code_imports[module] = set((cname,)) else: self._code_imports[module].add(cname) return cname def _process_imports(self): lines = [] s = 'import tkinter as tk' lines.append(s) if self._import_ttk: s = 'import tkinter.ttk as ttk' lines.append(s) skeys = sorted(self._code_imports.keys()) for mname in skeys: names = sorted(self._code_imports[mname]) for group in grouper(names, 4): bag = [] for cname in group: if cname is not None: bag.append(cname) clist = None if len(bag) > 1: clist = '({0})'.format(', '.join(bag)) else: clist = ''.join(bag) line = 'from {0} import {1}'.format(mname, clist) lines.append(line) return lines def code_create_variable(self, name_or_desc, value, vtype=None): vname, type_from_name = self._process_variable_description(name_or_desc) if vname not in self._tkvariables: var_init = '' if value is None: value = '' else: if type_from_name == 'string': value = "''".format(value) if vtype is None: var_init = 'tk.{0}Var({1})'.format(type_from_name.capitalize(), value) else: var_init = '{0}({1})'.format(str(vtype), value) line = '{0} = {1}'.format(vname, var_init) self._code.append(line) self._tkvariables[vname] = vtype return vname def _code_realize(self, bmaster, wmeta): originalid = wmeta.identifier uniqueid = None if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() if self.as_class: if not masterid: uniqueid = 'self' else: uniqueid = 'self.' + uniqueid create = builder.code_realize(bmaster, uniqueid) self._code.extend(create) # Children for childmeta in \ self.uidefinition.widget_children(originalid): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) # configuration configure = builder.code_configure() self._code.extend(configure) # layout layout = builder.code_layout() self._code.extend(layout) # callbacks commands = builder.code_connect_commands() bindings = builder.code_connect_bindings() self._code.extend(commands) self._code.extend(bindings) else: msg = 'Class "{0}" not mapped'.format(wmeta.classname) raise Exception(msg) return uniqueid def _process_callbacks(self): tabspaces = self._options['tabspaces'] tab2 = tabspaces//2 if tabspaces == 8 else 1 lines = [] for name, cbtype in self._callbacks.items(): if cbtype == 'command': line = '{0}def {1}(self):'.format(' '*tab2, name) else: line = '{0}def {1}(self, event=None):'.format(' '*tab2, name) lines.append(line) line = '{0}pass\n'.format(' '*tabspaces) lines.append(line) return lines def code_create_callback(self, name, cbtype): if name not in self._callbacks: self._callbacks[name] = cbtype cb_name = 'self.{0}'.format(name) return cb_name def code_create_image(self, filename): basename = os.path.basename(filename) name, file_ext = os.path.splitext(basename) name = self._make_identifier(basename) varname = 'self.{0}'.format(name) if filename not in self._tkimages: img_class = 'tk.PhotoImage' if file_ext in TK_BITMAP_FORMATS: img_class = 'tk.BitmapImage' line = "{0} = {1}(file='{2}')".format(varname, img_class, filename) self._code.append(line) self._tkvariables[varname] = True return varname def code_create_iconbitmap(self, filename): TPL = '@{0}' if os.name == 'nt': TPL = '{0}' return TPL.format(filename) def _make_identifier(self, name): output = name.replace('.', '_') output = ''.join(x for x in output if x.isalnum() or x == '_') return output
class UI2Code(Builder): def __init__(self): super(UI2Code, self).__init__() self.buffer = None self.as_class = False self._code_imports = OrderedDict() self._tkvariables = {} self._tkimages = {} self._callbacks = {} self._import_ttk = True self._code = [] # Used for preventing duplicate grid row/column configure lines from # ending up in the generated code. self._unique_grid_properties = [] self.uidefinition = None self._builder = Builder() self._options = {} def _process_options(self, kw): kwdef = {'as_class': True, 'tabspaces': 8} kwdef.update(kw) self._options = kwdef self.as_class = self._options['as_class'] self.tabspaces = self._options['tabspaces'] def _process_results(self, target): code = [] for line in self._code: line = '{0}{1}\n'.format(' ' * self.tabspaces, line) code.append(line) code = ''.join(code) code_imports = self._process_imports() code_imports = '\n'.join(code_imports) code_ttk_styles = self._process_ttk_styles() code_callbacks = self._process_callbacks() code_callbacks = '\n'.join(code_callbacks) code = ''.join(code) cc = { 'imports': code_imports, target: code, 'ttkstyles': code_ttk_styles, 'callbacks': code_callbacks, 'tkvariables': list(self._tkvariables.keys()) } return cc def _toplevel_or_tk(self, target): wmeta = self.uidefinition.get_widget(target) if wmeta.classname == 'tk.Toplevel': wmeta.classname = 'pygubudesigner.ToplevelOrTk' self.uidefinition.replace_widget(target, wmeta) def generate(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = WidgetMeta('', 'master') builder = BuilderObject(self, mastermeta) self._toplevel_or_tk(target) wmeta = self.uidefinition.get_widget(target) if wmeta is not None: self._code_realize(builder, wmeta) return self._process_results(target) def generate_widget_class(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = wmeta = self.uidefinition.get_widget(target) builder = bmaster = BuilderObject(self, mastermeta) if wmeta is not None: originalid = wmeta.identifier wmeta.identifier = 'self' if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() for childmeta in \ self.uidefinition.widget_children(target): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) # configuration configure = builder.code_configure() self._code.extend(configure) # layout? TODO: Review if layout is required here. layout = builder.code_layout(parentid=masterid) self._code.extend(layout) return self._process_results(target) def code_classname_for(self, bobject): wmeta = bobject.wmeta cname = None if bobject.class_ is not None: if wmeta.classname == 'pygubudesigner.ToplevelOrTk': cname = 'tk.Toplevel' elif wmeta.classname.startswith('tk.'): cname = wmeta.classname elif wmeta.classname.startswith('ttk.'): self._import_ttk = True cname = wmeta.classname else: module = bobject.class_.__module__ cname = bobject.class_.__name__ if module not in self._code_imports: self._code_imports[module] = set((cname, )) else: self._code_imports[module].add(cname) return cname def _process_ttk_styles(self): """ Generate the ttk style code. """ style_definition = StyleHandler.get_ttk_style_definitions() if not style_definition: return '' new_lines = [] # Make sure the ttk style code starts with 8 spaces for proper indentication # with the generated class. code_lines = style_definition.split('\n') for line in code_lines: if not line.startswith(' ' * self.tabspaces): line = ' ' * self.tabspaces + line new_lines.append(line) new_code = '\n'.join(new_lines) return new_code def _process_imports(self): lines = [] s = 'import tkinter as tk' lines.append(s) if self._import_ttk: s = 'import tkinter.ttk as ttk' lines.append(s) skeys = sorted(self._code_imports.keys()) for mname in skeys: names = sorted(self._code_imports[mname]) for group in grouper(names, 4): bag = [] for cname in group: if cname is not None: bag.append(cname) clist = None if len(bag) > 1: clist = '({0})'.format(', '.join(bag)) else: clist = ''.join(bag) line = 'from {0} import {1}'.format(mname, clist) lines.append(line) return lines def code_create_variable(self, name_or_desc, value, vtype=None): vname, type_from_name = self._process_variable_description( name_or_desc) vname_in_code = vname if vname not in self._tkvariables: var_init = '' if value is None: value = "''" else: if type_from_name == 'string': value = "'{0}'".format(value) if vtype is None: var_init = 'tk.{0}Var(value={1})'.format( type_from_name.capitalize(), value) else: var_init = '{0}(value={1})'.format(str(vtype), value) if self.as_class: vname_in_code = 'self.{0}'.format(vname) line = '{0} = {1}'.format(vname_in_code, var_init) self._code.append(line) self._tkvariables[vname] = vname_in_code return self._tkvariables[vname] def _code_realize(self, bmaster, wmeta): originalid = wmeta.identifier uniqueid = None if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() if self.as_class: if not masterid: uniqueid = 'self' else: uniqueid = 'self.' + uniqueid create = builder.code_realize(bmaster, uniqueid) self._code.extend(create) # Children for childmeta in \ self.uidefinition.widget_children(originalid): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) # configuration configure = builder.code_configure() self._code.extend(configure) # layout layout = builder.code_layout(parentid=masterid) # Prevent duplicate grid properties from making it to the final # generated code. # For example: there may be 2 widgets that have a grid column weight of 1. The generated code # will make the parent's columnconfigure property to weight='1', but it'll do it two times (once for each widget). # The code below will prevent it from having the same grid # configuration code generated twice. idx_to_remove = [] for idx, l in enumerate(layout): # Do we already have the property added to the code? If so, # record the index so we can remove the duplicate line. if l in self._unique_grid_properties: idx_to_remove.append(idx) else: self._unique_grid_properties.append(l) # Remove duplicate lines that we already have (such as for example: # self.frame1.columnconfigure(0, weight='1')) layout = [ item for idx, item in enumerate(layout) if idx not in idx_to_remove ] self._code.extend(layout) # callbacks commands = builder.code_connect_commands() bindings = builder.code_connect_bindings() self._code.extend(commands) self._code.extend(bindings) else: msg = 'Class "{0}" not mapped'.format(wmeta.classname) raise Exception(msg) return uniqueid def _process_callbacks(self): tabspaces = self._options['tabspaces'] tab2 = tabspaces // 2 if tabspaces == 8 else 1 lines = [] for name, value in self._callbacks.items(): wid, cbtype, args = value if cbtype == CB_TYPES.BIND_EVENT: line = '{0}def {1}(self, event=None):'.format(' ' * tab2, name) lines.append(line) line = '{0}pass\n'.format(' ' * tabspaces) lines.append(line) elif cbtype == CB_TYPES.SCROLL: fargs = [] for a in args: fargs.append('{0}=None'.format(a)) fargs = ', '.join(fargs) line = '{0}def {1}(self, {2}):'.format(' ' * tab2, name, fargs) lines.append(line) line = '{0}pass\n'.format(' ' * tabspaces) lines.append(line) else: # other types: cb_simple, cb_with_id, etc. if args is None: line = '{0}def {1}(self):'.format(' ' * tab2, name) lines.append(line) line = '{0}pass\n'.format(' ' * tabspaces) lines.append(line) else: fargs = ', '.join(args) line = '{0}def {1}(self, {2}):'.format( ' ' * tab2, name, fargs) lines.append(line) line = '{0}pass\n'.format(' ' * tabspaces) lines.append(line) return lines def code_create_callback(self, widgetid, cbname, cbtype, args=None): #print('on_code_create_callback', widgetid, cbname, cbtype, args) if cbname not in self._callbacks: self._callbacks[cbname] = (widgetid, cbtype, args) cb_name = 'self.{0}'.format(cbname) return cb_name def code_create_image(self, filename): if filename not in self._tkimages: basename = os.path.basename(filename) name, file_ext = os.path.splitext(basename) name = self._make_identifier(name) varname = 'self.img_{0}'.format(name) img_class = 'tk.PhotoImage' if file_ext in TK_BITMAP_FORMATS: img_class = 'tk.BitmapImage' line = "{0} = {1}(file='{2}')".format(varname, img_class, filename) self._code.append(line) self._tkimages[filename] = varname return self._tkimages[filename] def code_create_iconbitmap(self, filename): TPL = '@{0}' if os.name == 'nt': TPL = '{0}' return TPL.format(filename) def _make_identifier(self, name): output = name.replace('.', '_') output = ''.join(x for x in output if x.isalnum() or x == '_') return output
class UI2Code(Builder): def __init__(self): super().__init__() self._script_type = None self.as_class = False self._extra_imports = {} self._code_imports = OrderedDict() self._tkvariables = {} self._tkimages = {} self._callbacks = {} self._import_tk = False self._import_ttk = False self._code = [] # Used for preventing duplicate grid row/column configure lines from # ending up in the generated code. self._unique_grid_properties = [] self.uidefinition = None self._builder = Builder() self._options = {} self._with_i18n_support = False def add_import_line(self, module_name, as_name=None, priority=0): if module_name not in self._extra_imports: self._extra_imports[module_name] = (as_name, priority) def _process_options(self, kw): kwdef = { 'as_class': True, 'tabspaces': 8, 'script_type': ScriptType.APP_WITH_UI, } kwdef.update(kw) self._options = kwdef self.as_class = self._options['as_class'] self.tabspaces = self._options['tabspaces'] self._script_type = self._options['script_type'] def _process_results(self, target): code = [] for line in self._code: line = '{}{}\n'.format(' ' * self.tabspaces, line) code.append(line) code = ''.join(code) code_imports = self._process_imports() code_imports = '\n'.join(code_imports) code_ttk_styles = self._process_ttk_styles() code_callbacks = self._process_callbacks() code_callbacks = '\n'.join(code_callbacks) code = ''.join(code) cc = { 'imports': code_imports, target: code, 'ttkstyles': code_ttk_styles, 'callbacks': code_callbacks, 'tkvariables': list(self._tkvariables.keys()), } return cc def _toplevel_or_tk(self, target): wmeta = self.uidefinition.get_widget(target) if wmeta.classname == 'tk.Toplevel': wmeta.classname = 'pygubudesigner.ToplevelOrTk' self.uidefinition.replace_widget(target, wmeta) def generate(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = WidgetMeta('', 'master') builder = BuilderObject(self, mastermeta) self._toplevel_or_tk(target) wmeta = self.uidefinition.get_widget(target) if wmeta is not None: self._code_realize(builder, wmeta) return self._process_results(target) def generate_app_with_ui(self, uidef, target): return self.generate( uidef, target, as_class=False, tabspaces=8, script_type=ScriptType.APP_WITH_UI, ) def generate_app_code(self, uidef, target): return self.generate( uidef, target, as_class=True, tabspaces=8, script_type=ScriptType.APP_CODE ) def generate_app_widget(self, uidef, target): return self.generate_widget_class(uidef, target, script_type=ScriptType.WIDGET) def generate_widget_class(self, uidef, target, **kw): self.uidefinition = uidef self._process_options(kw) mastermeta = wmeta = self.uidefinition.get_widget(target) builder = bmaster = BuilderObject(self, mastermeta) if wmeta is not None: originalid = wmeta.identifier wmeta.identifier = 'self' if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() for childmeta in self.uidefinition.widget_children(target): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) # configuration configure = builder.code_configure() self._code.extend(configure) # layout? TODO: Review if layout is required here. layout = builder.code_layout(parentid=masterid) self._code.extend(layout) return self._process_results(target) def code_classname_for(self, bobject): wmeta = bobject.wmeta cname = None if bobject.class_ is not None: if wmeta.classname == 'pygubudesigner.ToplevelOrTk': self._import_tk = True cname = 'tk.Toplevel' elif wmeta.classname.startswith('tk.'): self._import_tk = True cname = wmeta.classname elif wmeta.classname.startswith('ttk.'): self._import_ttk = True cname = wmeta.classname else: module = bobject.class_.__module__ cname = bobject.class_.__name__ if module not in self._code_imports: self._code_imports[module] = {cname} else: self._code_imports[module].add(cname) return cname def _process_ttk_styles(self): """ Generate the ttk style code. """ style_definition = StyleHandler.get_ttk_style_definitions() if not style_definition: return '' new_lines = [] # Make sure the ttk style code starts with 8 spaces for proper indentication # with the generated class. code_lines = style_definition.split('\n') for line in code_lines: if not line.startswith(' ' * self.tabspaces): line = ' ' * self.tabspaces + line new_lines.append(line) new_code = '\n'.join(new_lines) return new_code def _process_imports(self): lines = [] if self._script_type in (ScriptType.APP_CODE, ScriptType.WIDGET): if self._import_tk: self.add_import_line('tkinter', 'tk') if self._import_ttk: self.add_import_line('tkinter.ttk', 'ttk', priority=2) sorted_imports = sorted( self._extra_imports.items(), key=lambda x: (x[1][1], x[0]) ) for module_name, (as_name, _) in sorted_imports: line = f'import {module_name}' if as_name is not None: line = line + f' as {as_name}' lines.append(line) # Do not include code imports if using UI file. if self._script_type != ScriptType.APP_WITH_UI: skeys = sorted(self._code_imports.keys()) for mname in skeys: names = sorted(self._code_imports[mname]) for group in grouper(names, 4): bag = [] for cname in group: if cname is not None: bag.append(cname) clist = None if len(bag) > 1: clist = '({})'.format(', '.join(bag)) else: clist = ''.join(bag) line = f'from {mname} import {clist}' lines.append(line) return lines def code_create_variable(self, name_or_desc, value, vtype=None): vname, type_from_name = self._process_variable_description(name_or_desc) vname_in_code = vname if vname not in self._tkvariables: var_init = '' if value is None: value = "''" else: if type_from_name == 'string': value = f"{value}" if vtype is None: var_init = 'tk.{}Var(value={})'.format( type_from_name.capitalize(), value ) else: var_init = f'{str(vtype)}(value={value})' if self.as_class: vname_in_code = f'self.{vname}' line = f'{vname_in_code} = {var_init}' self._code.append(line) self._tkvariables[vname] = vname_in_code return self._tkvariables[vname] def _code_realize(self, bmaster, wmeta): originalid = wmeta.identifier uniqueid = None if wmeta.classname not in CLASS_MAP: self._builder._import_class(wmeta.classname) if wmeta.classname in CLASS_MAP: bclass = CLASS_MAP[wmeta.classname].builder builder = bclass.factory(self, wmeta) uniqueid = builder.code_identifier() masterid = bmaster.code_child_master() if self.as_class: if not masterid: uniqueid = 'self' else: uniqueid = 'self.' + uniqueid create = builder.code_realize(bmaster, uniqueid) self._code.extend(create) # Children for childmeta in self.uidefinition.widget_children(originalid): childid = self._code_realize(builder, childmeta) code = builder.code_child_add(childid) self._code.extend(code) # configuration configure = builder.code_configure() self._code.extend(configure) # layout layout = builder.code_layout(parentid=masterid) self._code.extend(layout) # callbacks commands = builder.code_connect_commands() bindings = builder.code_connect_bindings() self._code.extend(commands) self._code.extend(bindings) else: msg = f'Class "{wmeta.classname}" not mapped' raise Exception(msg) return uniqueid def _process_callbacks(self): tabspaces = self._options['tabspaces'] tab2 = tabspaces // 2 if tabspaces == 8 else 1 lines = [] for name, value in self._callbacks.items(): wid, cbtype, args = value if cbtype == CB_TYPES.BIND_EVENT: line = '{}def {}(self, event=None):'.format(' ' * tab2, name) lines.append(line) line = '{}pass\n'.format(' ' * tabspaces) lines.append(line) elif cbtype == CB_TYPES.SCROLL: fargs = [] for a in args: fargs.append(f'{a}=None') fargs = ', '.join(fargs) line = '{}def {}(self, {}):'.format(' ' * tab2, name, fargs) lines.append(line) line = '{}pass\n'.format(' ' * tabspaces) lines.append(line) else: # other types: cb_simple, cb_with_id, etc. if args is None: line = '{}def {}(self):'.format(' ' * tab2, name) lines.append(line) line = '{}pass\n'.format(' ' * tabspaces) lines.append(line) else: fargs = ', '.join(args) line = '{}def {}(self, {}):'.format(' ' * tab2, name, fargs) lines.append(line) line = '{}pass\n'.format(' ' * tabspaces) lines.append(line) return lines def code_create_callback(self, widgetid, cbname, cbtype, args=None): # print('on_code_create_callback', widgetid, cbname, cbtype, args) if cbname not in self._callbacks: self._callbacks[cbname] = (widgetid, cbtype, args) cb_name = f'self.{cbname}' return cb_name def code_create_image(self, filename): if filename not in self._tkimages: basename = os.path.basename(filename) name, file_ext = os.path.splitext(basename) name = self._make_identifier(name) varname = f'self.img_{name}' img_class = 'tk.PhotoImage' if file_ext in TK_BITMAP_FORMATS: img_class = 'tk.BitmapImage' line = f"{varname} = {img_class}(file='{filename}')" self._code.append(line) self._tkimages[filename] = varname return self._tkimages[filename] def code_create_iconbitmap(self, filename): TPL = '@{0}' if os.name == 'nt': TPL = '{0}' return TPL.format(filename) def _make_identifier(self, name): output = name.replace('.', '_') output = ''.join(x for x in output if x.isalnum() or x == '_') return output def code_translate_str(self, value: str) -> str: escaped = BuilderObject.code_escape_str(value) if self.with_i18n_support: trval = f'_({escaped})' return trval else: return escaped @property def with_i18n_support(self) -> bool: return self._with_i18n_support @with_i18n_support.setter def with_i18n_support(self, value: bool): self._with_i18n_support = value