Launcher.tkLauncherApp のソースコード

"""
概要:
    tkLauncherApp は、Pythonスクリプトランチャー機能を提供するTkinterアプリケーションです。
詳細説明:
    このモジュールは、tkApplication_GUIを継承し、スクリプトの実行、設定の管理、
    各種ダイアログの表示、ファイルの操作など、幅広い機能を提供します。
    ユーザーはINIファイルを介してアプリケーションの動作をカスタマイズでき、
    スクリプト変数を介してスクリプトとアプリケーション間でデータをやり取りできます。
主な機能:
    - スクリプト変数の設定と管理
    - OSパス区切り文字の自動変換
    - INIファイルの読み書き
    - ファイル/ディレクトリ選択ダイアログの表示
    - カスタムダイアログ、選択ダイアログ、入力ダイアログの表示
    - ツールチップとコンテキストメニューの管理
    - ウィンドウ状態の制御 (最小化、最大化、最前面表示など)
    - ファイルの検索とリスト取得
関連リンク:
    tkLauncherApp_usage
"""
import sys
import os
import re
import glob
import openpyxl
import pandas as pd
import tkinter

from tklib.tkutils import pconv, pint, pfloat, terminate, del_quote
from tklib.tkutils import get_os, split_file_path, get_last_directory, get_upper_directory, split_drive, find_executable_path
from tklib.tkutils import add_path, del_quote, split_command_line
from tklib.tkutils import find_latest_file, find_files
from tklib.tkparams import tkParams
from tklib.tkfile import tkFile
from tklib.tkinifile import tkIniFile
from tklib.tkexcel_db import tkExcelDB
from tklib.tkgui.tkapplication_gui import tkApplication_GUI
import tklib.tkgui.tktkinter as tktkinter
from tklib.tkgui.tktkinter import dialog_showinfo, tkInputDialog, tkSelectDialog, tkCustomDialog_by_config
from tklib.tkscript_macro import tkScript

from tklib.tkgui.tktooltip import tkTooltip
from tklib.tkgui.tkmenu_popup import tkMenu_popup

[ドキュメント] class tkLauncherApp(tkApplication_GUI): """ 概要: Pythonスクリプトの実行と管理を行うためのGUIアプリケーションクラスです。 詳細説明: tkApplication_GUIを継承し、スクリプト変数の設定、INIファイルの操作、 各種ダイアログの表示、GUI要素へのツールチップやコンテキストメニューの追加、 ウィンドウ状態の制御など、ランチャーアプリケーションとして必要な機能を提供します。 引数: :param args: アプリケーション初期化のためのキーワード引数。 :type args: dict """ def __init__(self, **args): """ 概要: tkLauncherAppのインスタンスを初期化します。 詳細説明: エラー変数の初期設定、以前のポップアップメニューのクリア、 ダイアログ設定リストの初期化を行い、親クラスのコンストラクタを呼び出します。 引数: :param args: アプリケーション初期化のためのキーワード引数。 :type args: dict """ self.alert_var_error = True self.prev_popup_menu = None self.dialog_config = [] #tkParams() super().__init__(**args)
[ドキュメント] def set_var(self, var, val, set_env = False): """ 概要: 指定された変数に値を設定します。 詳細説明: 内部のスクリプト変数管理システムと、必要に応じて環境変数に値を設定します。 引数: :param var: 設定する変数名。 :type var: str :param val: 変数に設定する値。 :type val: str :param set_env: Trueの場合、環境変数にも設定します。 :type set_env: bool """ # print(f"set: {var=} {val=} {set_env=}") var_l = var.lower() self.s_engine.vars[var_l] = val self.svars.get_param_dict()[var] = val # print(f"tkLauncherApp.set_var 31: {var_l=} {self.s_engine.vars[var_l]=}") if set_env: os.environ[var] = val
[ドキュメント] def convert_os_path_sep(self, path): """ 概要: 指定されたパスの区切り文字を現在のOSに適した形式に変換します。 引数: :param path: 変換するパス文字列。 :type path: str 戻り値: :returns: OSのパス区切り文字に変換されたパス文字列。 :rtype: str """ os_name = get_os() if os_name == 'Windows': val = path.replace('/', '\\') val = path.replace('\\\\', '\\') else: val = path.replace('\\', '/') val = path.replace('//', '/') return val
[ドキュメント] def use_os_path_sep(self, var): """ 概要: 指定された変数に格納されているパスの区切り文字を現在のOSに適した形式に変換し、 その変数を更新します。 引数: :param var: パスが格納されている変数名。 :type var: str """ os_name = get_os() val = self.s_engine.vars.get(var.lower(), "") if val is None: val = '' if os_name == 'Windows': val = val.replace('/', '\\') val = val.replace('\\\\', '\\') else: val = val.replace('\\', '/') val = val.replace('//', '/') self.set_var(var, val)
[ドキュメント] def echo(self, arg): """ 概要: 警告メッセージを出力します。 引数: :param arg: 出力するメッセージ。 :type arg: str """ self.print_warning(arg)
[ドキュメント] def update_script_vars(self, cparams): """ 概要: スクリプトで使用される変数をアプリケーションの状態に基づいて更新します。 詳細説明: 環境変数、設定値、Tkinter変数の値などを収集し、 スクリプトエンジンとアプリケーションの変数辞書を更新します。 引数: :param cparams: コマンドパラメータを含むオブジェクト。 :type cparams: object """ svars = self.svars vars = svars.get_param_dict() config = self.config ctkvars = self.tkvars tkvars = ctkvars.get_param_dict() env = self.env argv = self.argv vars.update(env) # vars.update(self.config.__dict__) keys = ["editor_path"] for key in keys: vars[key] = self.config.get(key, None) keys = ["os_name", "tkProg_Root", "tklib_Root", "pythonlib_path", "perllib_path", "tkprog_path", "tkprog_X_path", "internal_editor_path", "tkapp_path", "tkapp_open_path", "tkapp_etc_path" ] # "python_path", "perl_path"] for key in keys: vars[key] = self.get(key, None) keys = ["script_list_name", "script_list_path"] for key in keys: vars[key] = cparams.get(key, None) keys = ["lang", "python3_path", "python2_path", "python_path", "perl_path", "start_path", "shell_path", "filer_path", "vesta_path"] for key in keys: vars[key] = config.get(key, None) vars['n'] = '\n' vars['p'] = self.script_path vars['i'] = self.inifile vars['s'] = os.getcwd() vars['w'] = env.get("windir", "") if 'sel_file' in tkvars.keys(): vars['o'] = tkvars['sel_file'].get() if 'argument' in tkvars.keys(): vars['args'] = tkvars['argument'].get() vars['shell'] = env.get("ComSpec", "") s = '' for i in range(len(argv)): vars[f"{i}"] = argv[i] s += argv[i] + ' ' vars['a'] = s.strip()
[ドキュメント] def add_path(self, args): """ 概要: 指定されたパスを環境変数PATHまたは指定された変数に追加します。 引数: :param args: パス追加の引数リスト。 args[0]がパスの場合、PATHに追加。 args[0]が変数名、args[1]がパスの場合、変数名にパスを追加。 :type args: list of str """ n = len(args) if n >= 2: varname = args[0] path = args[1] else: varname = 'PATH' path = args[0] add_path(path, varname = varname) self.set_var(varname, os.environ[varname], set_env = True)
# vars = self.svars.get_param_dict() # vars['PATH'] = os.environ['PATH']
[ドキュメント] def debug(self): """ 概要: デバッグモードの状態を返します。 戻り値: :returns: デバッグモードが有効な場合はTrue、それ以外はFalse。 :rtype: bool """ return self.config.debug
[ドキュメント] def set_debug(self, f): """ 概要: デバッグモードを設定します。 引数: :param f: デバッグモードをTrueまたはFalseで設定します。 :type f: bool """ self.config.debug = f
[ドキュメント] def confirm(self): """ 概要: 確認モードの状態を返します。 戻り値: :returns: 確認モードが有効な場合はTrue、それ以外はFalse。 :rtype: bool """ return self.config.confirm
[ドキュメント] def set_confirm(self, f): """ 概要: 確認モードを設定します。 引数: :param f: 確認モードをTrueまたはFalseで設定します。 :type f: bool """ self.config.confirm = f
[ドキュメント] def create_script(self): """ 概要: スクリプトファイルからtkScriptオブジェクトを生成します。 戻り値: :returns: 生成されたtkScriptオブジェクト。 :rtype: tkScript """ script_files = sorted(self.script_files.items()) files = [d[1]["path"] for d in script_files] return tkScript(files)
[ドキュメント] def set(self, argline, do_set = True): """ 概要: 指定された引数行から変数名と値を解析し、変数を設定します。 引数: :param argline: 設定する変数と値を含む文字列(例: "VAR_NAME=VALUE")。 :type argline: str :param do_set: Trueの場合、実際に変数を設定します。Falseの場合、解析のみ行います。 :type do_set: bool """ s = argline.strip() var = None val = None m = re.match(r'([\w\.\_]+)\s*=(.*)$', s, flags = re.MULTILINE | re.DOTALL) if not m: var = s val = '' else: g = m.groups() var = g[0] val = del_quote(g[1].strip()) if do_set: self.set_var(var, val, set_env = False)
[ドキュメント] def list_append(self, args, check_exist = False): """ 概要: 指定された変数に、複数の値をリスト形式(区切り文字は'#')で追加します。 引数: :param args: 最初の要素が変数名、以降の要素が追加する値のリスト。 :type args: list of str :param check_exist: Trueの場合、追加する値がファイルとして存在するかチェックします。 :type check_exist: bool """ svars = self.svars varname = args[0] val = svars.get(varname, '') for v in args[1:]: if v == '': continue if not check_exist: if val == '': val = v else: val += '#' + v elif os.path.isexist(v): if val == '': val = v else: val += '#' + v # self.print_warning(f"set [{val}] to [{varname}]") self.set_var(varname, val, set_env = False)
[ドキュメント] def set_path(self, argline): """ 概要: 引数行からパス変数とその値を設定し、OSのパス区切り文字に変換します。 引数: :param argline: 設定するパス変数と値を含む文字列(例: "PATH_VAR=C:/path/to/dir")。 :type argline: str """ self.set(argline, do_set = False) a = argline.split(' ') self.use_os_path_sep(a[0])
[ドキュメント] def join_path(self, args): """ 概要: 複数のパス要素を結合し、OSのパス区切り文字に変換して変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、以降の要素が結合するパス。 :type args: list of str """ varname = args[0] if len(args) >= 3: p = os.path.join(args[1], *args[2:]) else: p = args[1] # print("tkLauncherApp.join_path 207: ", args, len(args), p) p = self.convert_os_path_sep(p) self.set_var(varname, p, set_env = False)
[ドキュメント] def split_argline(self, argline): """ 概要: 引数行を解析し、変数名、現在の値、コマンド部分を抽出します。 引数: :param argline: 解析する引数行文字列(例: "VAR_NAME SOME_COMMAND=VALUE")。 :type argline: str 戻り値: :returns: (変数名, 変数の現在の値, コマンド部分) のタプル。解析に失敗した場合は (None, None, None)。 :rtype: tuple or None """ s = argline.strip() var = None command = None m = re.match(r'(\S+)\s+(\S.*=.*)$', s, flags = re.MULTILINE | re.DOTALL) if not m: self.print_warning(f"Error in tkLauncherApp.split_argline(): Invalid argline [{argline}]") return None, None, None g = m.groups() var = g[0] command = del_quote(g[1].strip()) val = self.svars.get(var, None) return var, val, command
[ドキュメント] def set_if_not_blank(self, argline): """ 概要: 指定された変数に値があり、かつ空白でない場合に、コマンドを実行して変数を設定します。 引数: :param argline: 変数名と設定コマンドを含む文字列(例: "VAR_NAME NEW_VAR=NEW_VALUE")。 :type argline: str """ var, val, command = self.split_argline(argline) if val is not None and val != '': self.set(command)
[ドキュメント] def set_if_not_null(self, argline): """ 概要: 指定された変数がNoneでない場合に、コマンドを実行して変数を設定します。 引数: :param argline: 変数名と設定コマンドを含む文字列。 :type argline: str """ var, val, command = self.split_argline(argline) if val is not None: self.set(command)
[ドキュメント] def set_if_blank(self, argline): """ 概要: 指定された変数がNoneまたは空白の場合に、コマンドを実行して変数を設定します。 引数: :param argline: 変数名と設定コマンドを含む文字列。 :type argline: str """ var, val, command = self.split_argline(argline) # val = self.svars.get(var, None) if val is None or val == '': self.set(command)
[ドキュメント] def set_if_null(self, argline): """ 概要: 指定された変数がNoneの場合に、コマンドを実行して変数を設定します。 引数: :param argline: 変数名と設定コマンドを含む文字列。 :type argline: str """ var, val, command = self.split_argline(argline) if val is None: self.set(command)
[ドキュメント] def get_app_path(self, args): """ 概要: アプリケーションの実行可能ファイルのパスを取得します。 詳細説明: 指定された変数にパスが設定されていないか、ファイルが存在しない場合、 ファイル選択ダイアログを表示してユーザーに選択を促し、結果を変数に保存します。 引数: :param args: 最初の要素がパスを格納する変数名、二番目の要素がファイルマスク、 三番目の要素がダイアログのメッセージ。 :type args: list of str 戻り値: :returns: パスが正常に取得または設定された場合はTrue、ユーザーがキャンセルした場合はFalse。 :rtype: bool """ vars = self.s_engine.vars varname = args[0] path = vars.get(varname, None) fmask = args[1] message = args[2] is_ok = True if path is None: self.print_warning(f"Warning: tkLauncherApp.get_app_path(): Variable [{varname}] is not defined.") is_ok = False elif not os.path.isfile(path): self.print_warning(f"Warning: tkLauncherApp.get_app_path(): [{path}] is not a file.") is_ok = False if not is_ok: ftype = [("Specified", fmask), ("All", "*.*")] selpath = tkinter.filedialog.askopenfilename(filetypes = ftype, initialdir = '.', title = message) if not selpath: return False self.set_var(varname, selpath, set_env = True) self.print(f"config {varname} is set to {selpath}") config = self.configparams config.set(varname, selpath) # self.print_warning(f"tkLauncherApp.get_app_path(): config:") # config.print_parameters(app = self, use_warning = True) return True
[ドキュメント] def save_config(self, argline): """ 概要: アプリケーションの設定をINIファイルに保存します。 詳細説明: 現在のウィンドウのジオメトリ情報も設定にコピーされ、 指定されたINIファイルにすべての設定がソートされて書き込まれます。 引数: :param argline: 使用しない(将来の拡張用)。 :type argline: str """ config = self.config # ウィジェットの設定tkvarsをcparams,confgにコピー # copy_tkvars(app, cparams, tkvars) # copy_tkvars(app, config, tkvars) # メインウインドウサイズをconfigにコピー config.geometry, w, h, x0, y0 = self.get_geometry() #self.root_window_geometry self.print_warning("") self.print_warning(f"Save configuration to [{config.inifile}]") config.save_parameters(path = config.inifile, section = 'Configure', sort_by_keys = True, IsPrint = False)
[ドキュメント] def print_all(self, args): """ 概要: 指定されたプレフィックスを持つ全てのスクリプト変数を警告として出力します。 引数: :param args: 最初の要素がプレフィックスとなる変数名。 :type args: list of str """ var = args[0] d = self.svars.get_param_dict() self.print_warning("") self.print_warning(f"Values in [{var}]") for key in d.keys(): m = re.search(rf"{var}\.(.*)$", key) if m: k = m.groups()[0] self.print_warning(f" {var}.{k}: [{d[key]}]")
[ドキュメント] def read_ini_all(self, args): """ 概要: INIファイルからすべてのセクションとキーを読み込み、変数に設定します。 詳細説明: 読み込まれた各キーと値は、指定された変数名プレフィックスを付けて スクリプト変数として格納されます。 引数: :param args: 最初の要素がINIファイルのパス、二番目の要素が変数名プレフィックス。 :type args: list of str """ path = args[0] var = args[1] ini = tkIniFile(path, 'r') inf = ini.read_all(path = None, AddSection = 0, IsPrint = False, encoding = None) if inf: for key in inf: self.print_warning(f" {key}: {inf[key]}") self.set_var(f"{var}.{key}", inf[key], set_env = False)
[ドキュメント] def read_ini_to_vars(self, args): """ 概要: INIファイルの内容を読み込み、各行を「キー=値」として解析し、変数に設定します。 引数: :param args: 最初の要素がINIファイルのパス、オプションで二番目の要素にdel_quoteを指定できます。 :type args: list of str 戻り値: :returns: ファイルが正常に読み込まれた場合はTrue、それ以外はFalse。 :rtype: bool """ path = args[0] if len(args) > 1: option = args[1] else: option = '' fp = tkFile(path, 'r') if not fp.fp: return False while 1: line = fp.readline() if not line: break top = line[0] if top in "#:'": continue m = re.search(r'^([a-zA-Z_\-\.]+)\s*=\s*(.*?)\s*$', line) # m = re.search(r'^\S[a-zA-Z_\-\.]\s*=\s*(.*?)\s*$', line) if m: g = m.groups() # print("g=", g) if 'del_quote' in option: val = del_quote(g[1]) else: val = g[1] self.set_var(g[0], val, set_env = False) # print(f"** read_ini: {g[0]}={g[1]}") return True
[ドキュメント] def read_ini(self, args): """ 概要: INIファイルから指定されたセクションとキーの値を変数に読み込みます。 引数: :param args: 最初の要素がINIファイルのパス、二番目の要素がセクション名、 三番目の要素がキー名、四番目の要素が結果を格納する変数名。 五番目の要素はオプションで、デフォルト値を指定できます。 :type args: list of str """ n = len(args) def_val = '' if n >= 4: path = args[0] section = args[1] key = args[2] var = args[3] if n >= 5: def_val = args[4] # print(f"read: {path=} {section=} {key=} {var=} {def_val=}") ini = tkIniFile(path, 'r') s = ini.get_string(section = section, key = key, def_val = def_val, is_print = False) self.set_var(var, s, set_env = False)
# print(f"{var=} {s=}")
[ドキュメント] def write_ini(self, args): """ 概要: INIファイルに指定されたセクションとキーの値を書き込みます。 引数: :param args: 最初の要素がINIファイルのパス、二番目の要素がセクション名、 三番目の要素がキー名、四番目の要素が書き込む値。 :type args: list of str """ n = len(args) def_val = '' if n >= 4: path = args[0] section = args[1] key = args[2] val = args[3] # print(f"write: {path=} {section=} {key=} {val=}") ini = tkIniFile(path) #, 'a') s = ini.write_string(section = section, key = key, value = val, is_print = False)
[ドキュメント] def setup(self, args = None): """ 概要: アプリケーションのセットアップダイアログを表示します。 詳細説明: 設定可能なウィジェットのリストに基づいてダイアログを構築し、 ログの出力先を設定します。 引数: :param args: 使用しない(将来の拡張用)。 :type args: list or None """ setup_widgets = 'editor_path|python3_path|python2_path|perl_path|' \ + 'start_path|shell_path|filer_path|vesta_path|confirm_on_exit|debug_mode|show_log' self.dialog_setup(entry_width = 50, button_width = 10, edit_button_width = 10, shell_button_width = 0, widgets = setup_widgets, is_print = True) config = self.config if self.show_log: self.redirects = ["stdout", config.logfile] else: self.redirects = [config.logfile]
[ドキュメント] def copy_config2svars(self, args): """ 概要: アプリケーションの設定値をスクリプト変数にコピーします。 詳細説明: configオブジェクト内の全てのキーと値を、"config.キー名" の形式でスクリプト変数に設定します。 引数: :param args: 使用しない。 :type args: list """ config = self.config svars = self.svars for key in config.keys(): val = config.get(key, None) # print("key=", key, val, svars) svars.set(f'config.{key}', val)
[ドキュメント] def copy_config2scars(self, args): """ 概要: アプリケーションの設定値をスクリプト変数にコピーします。 詳細説明: copy_config2svarsメソッドのエイリアスです。 引数: :param args: 使用しない。 :type args: list """ self.copy_config2svars(args)
[ドキュメント] def copy_svars2config(self, args): """ 概要: スクリプト変数のうち"config."プレフィックスを持つ値をアプリケーションの設定にコピーします。 引数: :param args: 使用しない。 :type args: list """ config = self.config svars = self.svars for key in svars.keys(): if 'config.' not in key: continue cname, varname = key.split('.') val = svars.get(key, None) config.set(varname, val)
[ドキュメント] def eval(self, args): """ 概要: 指定された式を評価し、結果を変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素が評価する式。 :type args: list of str """ ret = eval(args[1], self.globals, {} ) self.set_var(args[0], "{}".format(ret), set_env = False)
[ドキュメント] def show_font_dialog(self, args): """ 概要: フォント選択ダイアログを表示し、選択されたフォントを変数に設定します。 引数: :param args: 最初の要素がフォント名を格納する変数名。 :type args: list of str 戻り値: :returns: ユーザーが選択した場合1、キャンセルした場合-1。 :rtype: int """ var = args[0] font = tktkinter.font_dialog(app = self, color = self.svars.get(var, None)) if not font: self.print_warning("tkLauncherApp.show_font_dialog(): Cancelled") return -1 self.set_var(var, font, set_env = False) return 1
[ドキュメント] def show_color_dialog(self, args): """ 概要: 色選択ダイアログを表示し、選択された色を変数に設定します。 引数: :param args: 最初の要素が色名を格納する変数名。 :type args: list of str 戻り値: :returns: ユーザーが選択した場合1、キャンセルした場合-1。 :rtype: int """ var = args[0] color = tktkinter.color_dialog(color = self.svars.get(var, None)) if not color[0]: self.print_warning("tkLauncherApp.show_color_dialog(): Cancelled") return -1 self.set_var(var, color[1], set_env = False) return 1
[ドキュメント] def get_button(self, button_idx0): """ 概要: 指定されたインデックスまたは名前のボタンウィジェットを取得します。 引数: :param button_idx0: ボタンのインデックス(1から始まる数値)またはボタン名(例: "RButton1", "TButton2")。 :type button_idx0: str or int 戻り値: :returns: 対応するボタンウィジェットオブジェクト、見つからない場合はNone。 :rtype: object or None """ tkvars = self.tkvars.get_param_dict() button_idx = pint(button_idx0, None) if button_idx is None: m = re.match(r'(\w+)(\d+)$', button_idx0) if m: g = m.groups() bname = g[0] button_idx = pint(g[1]) - 1 if bname == 'RButton' and len(tkvars["rbuttons"]) > button_idx: return tkvars["rbuttons"][button_idx] elif bname == 'TButton' and len(tkvars["tbuttons"]) > button_idx: return tkvars["tbuttons"][button_idx] else: if len(tkvars["submenu_buttons"]) >= button_idx: return tkvars["submenu_buttons"][button_idx-1] return None
[ドキュメント] def create_menu(self, args, s_engine, cparams, fp): """ 概要: ポップアップメニューを作成し、Tkinter変数に格納します。 詳細説明: 引数で指定されたラベルとコマンドを持つサブメニュー項目を作成し、 指定された変数名でポップアップメニューオブジェクトを管理します。 引数: :param args: 最初の要素がメニューを格納する変数名、二番目の要素がメニューのタイトル。 以降は「キー=ラベル」「キー=コマンド」のペアでサブメニュー項目を指定。 :type args: list of str :param s_engine: スクリプト実行エンジンオブジェクト。 :type s_engine: object :param cparams: コマンドパラメータオブジェクト。 :type cparams: object :param fp: ファイルポインタまたは関連オブジェクト。 :type fp: object """ tkvars = self.tkvars.get_param_dict() varname = args[0] title = args[1] def append_menu(submenus, label, cmd, fp): submenus.append({ 'label': label, 'callback': lambda: s_engine.execute_a_command(self, cparams, cmd, fp = fp) }) submenus = [] for i in range(2, len(args), 2): key, label = args[i].split('=') key, cmd = args[i+1].split('=') # self.print_warning("401: ", label, cmd) append_menu(submenus, label, cmd, fp) tkvars[varname] = tkMenu_popup(parent = self.root_window, title = title, submenus = submenus, app = self)
[ドキュメント] def show_context_menu(self, args, event): """ 概要: 指定されたコンテキストメニューをイベント発生位置に表示します。 引数: :param args: 最初の要素が表示するメニューの変数名。 :type args: list of str :param event: Tkinterイベントオブジェクト。メニューの表示位置に使用されます。 :type event: tkinter.Event """ tkvars = self.tkvars.get_param_dict() menu = tkvars.get(args[0], None) x = event.x_root y = event.y_root menu.post(x, y)
[ドキュメント] def add_context_menu(self, args): """ 概要: 指定されたウィジェットにコンテキストメニューをバインドします。 引数: :param args: 最初の要素がメニューの変数名、二番目の要素がバインドするボタンの識別子。 :type args: list of str """ tkvars = self.tkvars.get_param_dict() menu = tkvars.get(args[0], None) button = self.get_button(args[1]) if menu is None: self.print_warning("") self.print_warning(f"Warning in tkLauncherApp.add_context_menu(): Cannot find menu var [{args[0]}]") self.print_warning("") return if button is None: self.print_warning("") self.print_warning(f"Warning in tkLauncherApp.add_context_menu(): Invalid button [{args[0]}]") self.print_warning("") return menu.bind_to_widget(button, shiftx = 20, shifty = 20)
[ドキュメント] def add_tooltip(self, args): """ 概要: 指定されたウィジェットにツールチップを追加します。 引数: :param args: 最初の要素がツールチップを付けるボタンの識別子、二番目の要素がツールチップのテキスト。 オプションで三番目の要素が背景色、四番目の要素が前景色。 :type args: list of str """ if not self.use_tooltip: return tkvars = self.tkvars.get_param_dict() nargs = len(args) button = self.get_button(args[0]) text = self.p(args[1]) kwargs = {} if nargs >= 3: kwargs['bg'] = args[2] if nargs >= 4: kwargs['fg'] = args[3] if button: tkTooltip(widget = button, text = text, **kwargs) else: self.print_warning("") self.print_warning(f"Warning in tkLauncherApp.add_tooltip(): Invalid button name [{args[0]}]") self.print_warning("")
[ドキュメント] def new_dialog(self): """ 概要: カスタムダイアログの設定を初期化します。 詳細説明: 以前の設定をクリアし、新しいダイアログ設定のためにdialog_configリストを空にします。 """ self.dialog_config = [] #tkParams()
[ドキュメント] def add_dialog(self, args): """ 概要: カスタムダイアログにウィジェットの設定を追加します。 詳細説明: 引数で指定されたウィジェットタイプ、変数名、およびその他のオプションを解析し、 dialog_configリストに追加してカスタムダイアログの構成要素とします。 引数: :param args: ウィジェットの設定情報を含むリスト。最初の要素はウィジェットタイプ、 二番目の要素は関連する変数名、以降はキー=値の形式でオプションを指定。 :type args: list of str """ p = tkParams() nargs = len(args) if nargs >= 1: p.widget = args[0] else: p.widget = '' if nargs >= 2: p.var = args[1] else: p.var = '' # print("args=", p.widget, p.var, args[2:]) d = {} v = [] for s in args[2:]: m = re.match(r"\s*(\S+?)\s*=\s*(.*)\s*$", s) # print("m=", m, s) if m: g = m.groups() # print("g=", g) key = g[0] val = g[1] if re.search(r'^(--|[A-Z])', key[0]) or re.search(r'[:/+\-#\$\\]', key[0]): v.append(s) else: d[key] = pconv(val) # print("key=", key, val) else: v.append(s) # print("args =", d) p.args = d p.vars = v self.dialog_config.append(p)
[ドキュメント] def post_custom_dialog(self, vars): """ 概要: カスタムダイアログからの戻り値を変数に設定します。 引数: :param vars: ダイアログから返された変数名の辞書と値。 :type vars: dict """ # print("") # print("Return variables") # print("ret.ret=", vars) for var in vars.keys(): val = vars[var] # print(f" {var}={val}") self.set_var(var, val, set_env = False)
[ドキュメント] def show_custom_dialog(self, args): """ 概要: 構成済みのカスタムダイアログをモーダルで表示します。 詳細説明: ユーザーがダイアログで入力した値は、post_custom_dialogを通じてスクリプト変数に反映されます。 引数: :param args: 最初の要素がダイアログのタイトル。オプションで二番目の要素にボタンの定義。 :type args: list of str 戻り値: :returns: ユーザーが確定した場合1、キャンセルした場合-1。 :rtype: int """ title = args[0] if len(args) > 1: buttons = args[1] else: buttons = None ret = tkCustomDialog_by_config(master = self.main_window, app = self, title = self.p(title), config = self.dialog_config, buttons = buttons, modeless = False, callback = lambda vars: self.post_custom_dialog(vars)) if ret is None or ret.ret is None: self.print_warning("tkLauncherApp.show_custom_dialog(): Cancelled") return -1 vars = ret.ret self.post_custom_dialog(vars) return 1
[ドキュメント] def post_custom_dialog_modeless(self, vars): """ 概要: モーダルレスなカスタムダイアログからの戻り値を変数に設定します。 引数: :param vars: ダイアログから返された変数名の辞書と値。 :type vars: dict """ for var in vars.keys(): val = vars[var] self.set_var(var, val, set_env = False)
[ドキュメント] def show_custom_dialog_modeless(self, args): """ 概要: 構成済みのカスタムダイアログをモーダルレスで表示します。 詳細説明: ユーザーがダイアログで入力した値は、post_custom_dialog_modelessを通じてスクリプト変数に反映されます。 引数: :param args: 最初の要素がダイアログのタイトル。オプションで二番目の要素にボタンの定義。 :type args: list of str 戻り値: :returns: ユーザーが確定した場合1、キャンセルした場合-1。 :rtype: int """ title = args[0] if len(args) > 1: buttons = args[1] else: buttons = None ret = tkCustomDialog_by_config(master = self.main_window, app = self, title = self.p(title), config = self.dialog_config, buttons = buttons, modeless = True, callback = lambda vars: self.post_custom_dialog_modeless(vars)) if ret is None or ret.ret is None: self.print_warning("tkLauncherApp.show_custom_dialog_modeless(): Cancelled") return -1 vars = ret.ret self.show_custom_dialog_modeless(vars) return 1
[ドキュメント] def show_select_dialog(self, args): """ 概要: 複数の選択肢から一つを選ぶダイアログを表示します。 詳細説明: 指定されたオプションリストの中からユーザーに選択を促し、 選択された値を変数に設定します。 引数: :param args: 最初の要素が選択結果を格納する変数名、二番目の要素がダイアログのタイトル、 三番目の要素がメッセージ、四番目以降の要素が選択肢のリスト。 :type args: list of str 戻り値: :returns: ユーザーが選択した場合1、キャンセルした場合-1。 :rtype: int """ var = args[0] title = args[1] message = args[2] options = args[3:] def_val = self.svars.get(var, "") for idx in range(len(options)): s = options[idx] s2 = re.sub(r'\s*#.*$', '', s).strip() if def_val == s2: def_val = s def_index = idx break width = self.config.get("width_selectbox", 50) height = self.config.get("height_selectbox", 10) idlg = tkSelectDialog(master = self.root_window, app = self, title = self.p(title), varname = var, message = message, options = options, width = width, height = height, def_index = def_index, is_print = False) s = idlg.ret if not s: self.print_warning("tkLauncherApp.show_select_dialog(): Cancelled") return -1 # ret = re.sub(r'\s*#.*$', '', s).strip() # self.set_var(var, ret, set_env = False) self.set_var(var, s, set_env = False) return 1
[ドキュメント] def input(self, args): """ 概要: ユーザーからの複数行入力を受け付けるダイアログを表示します。 詳細説明: ユーザーが入力したテキストは、指定された変数に設定されます。 入力内容に "@var=value" の形式が含まれる場合、それも変数として設定されます。 引数: :param args: 最初の要素が入力結果を格納する変数名。 オプションで二番目の要素にメッセージ、三番目の要素にタイトル。 :type args: list of str 戻り値: :returns: ユーザーが入力した場合1、キャンセルした場合-1。 :rtype: int """ var = None message = 'Input' title = 'Input' n = len(args) if n >= 1: var = args[0] if n >= 2: message = args[1] if n >= 3: title = args[2] initialvalue = self.s_engine.vars.get(var, "") idlg = tkInputDialog(master = self.root_window, app = self, title = title, message = message, width = self.config.width_input_editbox, height = self.config.height_input_editbox, def_val = initialvalue, is_print = False) s = idlg.ret # s = tktkinter.askstring(self, title = title, message = message, initialvalue = initialvalue) if not s: self.print_warning("tkLauncherApp.input(): Cancelled") # s = initialvalue return -1 lines = s.splitlines() line = '' for s in lines: s = s.strip() if len(s) < 1: continue # print("") # print(f"{s=}") if s[0] == '@': m = re.match(r'\@(\w+)\s*=(.*)$', s, re.MULTILINE | re.DOTALL) if m: g = m.groups() _var = g[0] val = g[1].strip() # print(f"set {_var=} {val=}") self.set_var(_var, val, set_env = False) var_l = _var.lower() # print(f"{var_l=} {self.s_engine.vars[var_l]=}") continue else: line += s + ' ' self.set_var(var, line, set_env = False) return 1
[ドキュメント] def del_quote(self, var): """ 概要: 指定された変数に格納されている文字列から引用符を削除し、変数を更新します。 引数: :param var: 引用符を削除する対象の変数名。 :type var: str """ val = self.s_engine.vars.get(var, "") print("del quote: ", val) s1 = del_quote(val) print(" => ", s1) self.set_var(var, s1, set_env = False)
[ドキュメント] def remove_comment(self, var): """ 概要: 指定された変数に格納されている文字列から、コメント部分(#以降)を削除し、変数を更新します。 引数: :param var: コメントを削除する対象の変数名。 :type var: str """ var_l = var.lower() # print(f"{var_l=}") val = self.s_engine.vars.get(var_l, "") # print(f"{val=}") s1 = re.sub(r'\s*#.*$', '', val) # print(f"{s1=}") self.set_var(var, s1, set_env = False)
[ドキュメント] def get_first_word(self, args): """ 概要: 指定された文字列から、最初の区切り文字までの部分(最初の単語)を取得し、変数に設定します。 引数: :param args: 最初の要素が対象文字列、二番目の要素が区切り文字、三番目の要素が結果を格納する変数名。 :type args: list of str """ s = args[0] sep = args[1] var = args[2] m = re.match(rf'\s*(.*?)\s*{sep}', s) if m: ret = m.groups()[0] self.set_var(var, ret, set_env = False)
[ドキュメント] def get_last_word(self, args): """ 概要: 指定された文字列から、最後の区切り文字以降の部分(最後の単語)を取得し、変数に設定します。 引数: :param args: 最初の要素が対象文字列、二番目の要素が区切り文字、三番目の要素が結果を格納する変数名。 :type args: list of str """ s = args[0] sep = args[1] var = args[2] m = re.search(rf'{sep}\s*(.*?)\s*$', s) if m: ret = m.groups()[0] self.set_var(var, ret, set_env = False)
[ドキュメント] def get_path_part(self, key, path, var): """ 概要: 指定されたパスから特定の要素(ドライブ、ディレクトリ名、ファイル名など)を抽出し、変数に設定します。 引数: :param key: 抽出するパスの要素を指定するキー('drive', 'dir', 'filename'など)。 :type key: str :param path: 解析対象のパス文字列。 :type path: str :param var: 結果を格納する変数名。 :type var: str """ apath = os.path.abspath(path) if os.path.isdir(apath): dirname, basename, filebody, ext = apath, '', '', '' else: dirname, basename, filebody, ext = split_file_path(apath) last_dir = get_last_directory(apath) upper_dir = get_upper_directory(apath) drive, dirname_wo_drive = split_drive(apath) if key == 'drive': self.set_var(var, drive, set_env = False) elif key == 'dir': self.set_var(var, dirname, set_env = False) elif key == 'dir_without_drive': self.set_var(var, dirname_wo_drive, set_env = False) elif key == 'last_dir': self.set_var(var, last_dir, set_env = False) elif key == 'upper_dir': self.set_var(var, upper_dir, set_env = False) elif key == 'filename': self.set_var(var, basename, set_env = False) elif key == 'filebody': self.set_var(var, filebody, set_env = False) elif key == 'ext': self.set_var(var, ext, set_env = False) else: if self.alert_var_error: self.show_error(f"tkLauncherApp.get_path_part(): Invalid key [{key}]")
[ドキュメント] def get_cur_dir(self, var): """ 概要: 現在の作業ディレクトリを取得し、指定された変数に設定します。 引数: :param var: 現在の作業ディレクトリを格納する変数名。 :type var: str """ self.set_var(var, os.getcwd(), set_env = False)
[ドキュメント] def get_cur_menu(self, var): """ 概要: 現在選択されているメニュー項目を取得し、指定された変数に設定します。 引数: :param var: 選択されたメニュー項目を格納する変数名。 :type var: str """ tkvars = self.tkvars.get_param_dict() sel = tkvars["menu_listbox"].curselection() if not sel: sel = self.cur_sel menu = tkvars["menu_listbox"].get(sel) self.set_var(var, menu)
[ドキュメント] def get_cur_menu_file(self, var): """ 概要: 現在選択されているメニュー項目に関連付けられたファイルパスを取得し、変数に設定します。 引数: :param var: ファイルパスを格納する変数名。 :type var: str 戻り値: :returns: 関連付けられたファイルパス。 :rtype: str """ tkvars = self.tkvars.get_param_dict() sel = tkvars["menu_listbox"].curselection() if not sel: sel = self.cur_sel menu = tkvars["menu_listbox"].get(sel) path, fp, line = \ self.s_engine.find_file_from_menu(self, menu, idx = None, task = None, script_files = None) self.set_var(var, path) return path
[ドキュメント] def get_cur_button_idx(self, var): """ 概要: 最後に押されたボタンのインデックスを取得し、変数に設定します。 引数: :param var: ボタンのインデックスを格納する変数名。 :type var: str 戻り値: :returns: 最後に押されたボタンのインデックス。 :rtype: int """ self.set_var(var, self.last_ibutton) return self.last_ibutton
[ドキュメント] def get_cur_button_caption(self, var): """ 概要: 最後に押されたボタンのキャプション(テキスト)を取得し、変数に設定します。 引数: :param var: ボタンのキャプションを格納する変数名。 :type var: str 戻り値: :returns: 最後に押されたボタンのキャプション。 :rtype: str """ tkvars = self.tkvars.get_param_dict() val = tkvars["submenu_buttons"][self.last_ibutton]["text"] self.set_var(var, self.last_ibutton) return val
[ドキュメント] def split_str(self, args): """ 概要: 指定された文字列を区切り文字で分割し、指定されたインデックスの要素を変数に設定します。 引数: :param args: 最初の要素が対象文字列、二番目の要素が区切り文字、三番目の要素が取得するインデックス、 四番目の要素が結果を格納する変数名。 :type args: list of str 戻り値: :returns: 分割された文字列の指定インデックスの要素。 :rtype: str """ str = args[0] sep = args[1] idx = pint(args[2]) var_name = args[3] a = str.split(sep)[idx] self.set_var(var_name, a) return a
[ドキュメント] def check_file_mode(self, args): """ 概要: ファイル存在チェックモードを設定します。 詳細説明: このモードは、check_existメソッドの動作に影響を与えます。 'true'または'false'で設定されます。 引数: :param args: 最初の要素がファイルチェックモードを示す文字列(例: 'auto', 'true', 'false')。 :type args: list of str """ mode = args[0] self.set_var('check_file_mode', mode)
[ドキュメント] def check_exist(self, args): """ 概要: ファイルまたはディレクトリの存在をチェックします。 詳細説明: check_file_modeの設定や実際のファイル存在状況に基づいて、 メッセージダイアログを表示したり、ボタンの表示を変更したりします。 引数: :param args: 最初の要素がチェック対象のファイルまたはディレクトリのパス。 オプションで二番目の要素に表示するメッセージ。 :type args: list of str 戻り値: :returns: ファイルまたはディレクトリが存在し、チェックモードが許可する場合はTrue、それ以外はFalse。 :rtype: bool """ path = args[0] if len(args) >= 2: message = args[1] else: message = None status = self.s_engine.vars.get('check_file_mode', 'auto') is_exist = os.path.exists(path) if status == 'true' or is_exist: return True tkvars = self.tkvars.get_param_dict() button = tkvars["submenu_buttons"][self.last_ibutton] caption = button["text"] # print(f"346 caption={caption} ibutton={self.last_ibutton}") # button.configure(font = ("", 8, "normal", "roman", "normal", "overstrike"), fg = "red") button.set_text('!!! ' + caption) self.show_message_dialog(message) return False
[ドキュメント] def exit_if_defined(self, mode, var): """ 概要: 指定された変数が定義されているか否かに応じて、アプリケーションの終了を制御します。 詳細説明: modeがTrueで変数が定義されている場合、またはmodeがFalseで変数が未定義の場合に、 エラーダイアログを表示し、Falseを返します。 このメソッド自体はアプリケーションを終了させません。 引数: :param mode: Trueの場合「定義されている場合に終了」、Falseの場合「未定義の場合に終了」。 :type mode: bool :param var: チェックする変数名。 :type var: str 戻り値: :returns: 終了条件に合致しなかった場合はTrue、合致した場合はFalse。 :rtype: bool """ # print("vars=", self.s_engine.vars) val = self.s_engine.vars.get(var, None) if mode is True and val is not None: tktkinter.dialog_showerror(self, title = 'Error', message = f"Variable [{var}] is defined. Exit.") return False # self.terminate(f"Terminated by exit_if_defined for [{var}]") # exit() elif mode is False and val is None: tktkinter.dialog_showerror(self, title = 'Error', message = f"Variable [{var}] is not defined. Exit.") return False # self.terminate(f"Terminated by exit_if_not_defined for [{var}]") # exit() return True
[ドキュメント] def exit_if_exist(self, mode, path): """ 概要: 指定されたファイルの存在状況に応じて、アプリケーションの終了を制御します。 詳細説明: modeがTrueでファイルが存在する場合、またはmodeがFalseでファイルが存在しない場合に、 エラーダイアログを表示し、Falseを返します。 このメソッド自体はアプリケーションを終了させません。 引数: :param mode: Trueの場合「存在する場合に終了」、Falseの場合「存在しない場合に終了」。 :type mode: bool :param path: チェックするファイルパス。 :type path: str 戻り値: :returns: 終了条件に合致しなかった場合はTrue、合致した場合はFalse。 :rtype: bool """ f = os.path.exists(path) if mode is True and f: tktkinter.dialog_showerror(self, title = 'Error', message = f"File [{path}] exists. Exit.") return False # self.terminate(f"Terminated by exit_if_exist for [{path}]") # exit() if mode is False and not f: tktkinter.dialog_showerror(self, title = 'Error', message = f"File [{path}] does not exist. Exit.") return False # self.terminate(f"Terminated by exit_if_not_exist for [{path}]") # exit() return True
[ドキュメント] def show_message_dialog2(app, message): """ 概要: 情報メッセージダイアログを表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: 表示するメッセージ。 :type message: str """ tktkinter.dialog_showinfo(app, title = 'Information', message = message)
[ドキュメント] def show_message_dialog(app, message): """ 概要: 情報メッセージダイアログを表示します。 詳細説明: メッセージから引用符を削除して表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: 表示するメッセージ。 :type message: str """ message = del_quote(message) tktkinter.dialog_showinfo(app, title = 'Information', message = message)
# app.root_window.after(1, lambda: app.show_message_dialog2(del_quote(message)))
[ドキュメント] def show_error_dialog2(app, message, terminate = False): """ 概要: エラーメッセージダイアログを表示します。 詳細説明: 必要に応じてアプリケーションを終了させます。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: 表示するエラーメッセージ。 :type message: str :param terminate: Trueの場合、ダイアログ表示後にアプリケーションを終了させます。 :type terminate: bool """ tktkinter.dialog_showerror(app, title = 'Error', message = message) if terminate: app.terminate("tkLauncherApp.show_error_dialog2(): terminated")
[ドキュメント] def show_error_dialog(app, message, terminate = False): """ 概要: エラーメッセージダイアログを表示します。 詳細説明: メッセージから引用符を削除して表示し、必要に応じてアプリケーションを終了させます。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: 表示するエラーメッセージ。 :type message: str :param terminate: Trueの場合、ダイアログ表示後にアプリケーションを終了させます。 :type terminate: bool """ message = del_quote(message) # app.root_window.after(1, lambda: app.show_error_dialog2(message, terminate)) tktkinter.dialog_showerror(app, title = 'Error', message = message) if terminate: app.terminate("tkLauncherApp.show_error_dialog(): terminated")
[ドキュメント] def ask_okcancel_dialog2(app, message): """ 概要: OK/キャンセルダイアログを表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: ダイアログに表示するメッセージ。 :type message: str 戻り値: :returns: ユーザーがOKをクリックした場合はTrue、キャンセルした場合はFalse。 :rtype: bool """ return tktkinter.dialog_okcancel(app, title = 'Confirm', message = message)
[ドキュメント] def ask_okcancel_dialog(app, message): """ 概要: OK/キャンセルダイアログを表示します。 詳細説明: メッセージから引用符を削除して表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: ダイアログに表示するメッセージ。 :type message: str 戻り値: :returns: ユーザーがOKをクリックした場合はTrue、キャンセルした場合はFalse。 :rtype: bool """ message = del_quote(message) return tktkinter.dialog_okcancel(app, title = 'Confirm', message = message)
[ドキュメント] def ask_yesno_dialog2(app, message): """ 概要: Yes/Noダイアログを表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: ダイアログに表示するメッセージ。 :type message: str 戻り値: :returns: ユーザーがYesをクリックした場合はTrue、Noをクリックした場合はFalse。 :rtype: bool """ # return tktkinter.dialog_yesno(app, title = 'Confirm', message = message) return tktkinter.tkdialog_yesno(master = app.main_window, title = 'Confirm', message = message)
[ドキュメント] def ask_yesno_dialog(app, message): """ 概要: Yes/Noダイアログを表示します。 詳細説明: メッセージから引用符を削除して表示します。 引数: :param app: アプリケーションのインスタンス。 :type app: tkLauncherApp :param message: ダイアログに表示するメッセージ。 :type message: str 戻り値: :returns: ユーザーがYesをクリックした場合はTrue、Noをクリックした場合はFalse。 :rtype: bool """ message = del_quote(message) return tktkinter.dialog_yesno(app, title = 'Confirm', message = message) # return tktkinter.tkdialog_yesno(master = app.main_window, title = 'Confirm', message = message) """ app.print_warning("") app.print_warning(message) s = input("Enter 'YES' to continue>>") if s == 'YES': return '' else: return '2' """ return app.root_window.after(1, lambda: app.ask_yesno_dialog2(del_quote(message)))
[ドキュメント] def read_labels(self, args): """ 概要: ExcelまたはCSVファイルからヘッダーラベルを読み込み、指定された変数に設定します。 詳細説明: tkExcelDBを使用してファイルのシートを読み込み、最初の行のラベルを取得します。 取得したラベルは'##'で連結された文字列として変数に設定されます。 引数: :param args: 最初の要素がファイルパス、二番目の要素がラベルを格納する変数名。 :type args: list of str 戻り値: :returns: 読み込まれたラベルの文字列、またはエラーが発生した場合は-1。 :rtype: str or int """ path = args[0] varname = args[1] xls = tkExcelDB(path, mode = 'r', table_name = None, OpenFile = True, CloseFile = True, description = 'MS-Excel input', IsPrint = True) if xls.ws is None: print(f"\nError in tkLauncherApp.read_labels(): Can not read worksheet from [{path}]") return -1 labels = xls.get_labels() """ if '.xls' in path: df = pd.read_excel(path, engine = 'openpyxl') else: df = pd.read_csv(path) if df.empty: return -1 labels = df.columns.tolist() """ labels = [f"{s}" for s in labels] labels = "##".join(labels) self.set_var(varname, labels, set_env = False) return labels
[ドキュメント] def get_file_list(self, args, target = 'file'): """ 概要: 指定されたディレクトリからファイルまたはディレクトリのリストを取得します。 詳細説明: 指定されたファイルマスクに一致するファイルまたはディレクトリを検索し、 結果をソートして'##'で連結された文字列として変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素が検索対象ディレクトリ、 三番目以降の要素がファイルマスクのリスト。 :type args: list of str :param target: 'file'でファイルを検索、'dir'でディレクトリを検索。両方含む場合は'filedir'など。 :type target: str 戻り値: :returns: 検索結果を'##'で連結した文字列。 :rtype: str """ varname = args[0] dir = args[1] fmasks = [] for fm in args[2:]: a = fm.split(';') fmasks.extend(a) files_dict = {} for a in fmasks: fmask = os.path.join(dir, a) files = glob.glob(fmask) for f in files: filename = None if 'file' in target and os.path.isfile(f): filename = os.path.basename(f) if 'dir' in target and os.path.isdir(f): filename = os.path.basename(f) if filename is not None: files_dict[filename] = 1 files = [f for f in sorted(files_dict.keys())] s = '##'.join(files) self.set_var(varname, s, set_env = False) return s
[ドキュメント] def escape_reg(self, args): """ 概要: 文字列を正規表現の特殊文字からエスケープし、結果を変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素がエスケープ対象の文字列。 :type args: list of str """ var = args[0] str = args[1] val = re.sub(r'([\$\\\/\(\)\[\]])', r'\\\1', str) self.set_var(var, val, set_env = False)
[ドキュメント] def replace(self, args): """ 概要: 文字列内の部分文字列を置換し、結果を変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素が対象文字列、 三番目の要素が置換元の部分文字列、四番目の要素が置換後の部分文字列。 :type args: list of str """ var = args[0] str = args[1] _from = args[2] _to = args[3] val = str.replace(_from, _to) self.set_var(var, val, set_env = False)
[ドキュメント] def set_dialog_values(self, args): """ 概要: カスタムダイアログ内のウィジェット(例: ComboBox)の選択肢を設定します。 引数: :param args: 最初の要素がウィジェットに関連付けられた変数名、二番目の要素が'##'で区切られた選択肢の文字列。 :type args: list of str 戻り値: :returns: ウィジェットの値が正常に設定された場合はTrue、それ以外はFalse。 :rtype: bool """ # print("\nset_dialog_values") var = args[0] str = args[1] dvars = self.__dict__.get("dialog_widget_vars", None) # print("dvars=", dvars) if dvars is None: return False # print("dvars=", dvars.__dict__) widget= dvars.__dict__.get(var, None) # print("widget=", widget) if widget is None: return False values = [] for s in str.split('##'): # print("insert", s) values.append(s) # print("values=", values) try: widget['values'] = values except: pass return True
[ドキュメント] def set_dialog_var(self, args): """ 概要: カスタムダイアログ内のTkinter変数(StringVarなど)の値を設定します。 引数: :param args: 最初の要素が変数名、二番目の要素が設定する値の文字列。 :type args: list of str """ var = args[0] str = args[1] dvars = self.__dict__.get("dialog_tkvars", None) # print("708") if dvars: ddict = dvars.__dict__ if ddict: try: # self.print_warning("try d.tkvars") ddict[var].set(str) return except: # self.print_warning("failed d.tkvars") pass # print("735") tkvars = self.tkvars.get_param_dict() tkdict = tkvars.get(var, None) if tkdict: tkdict[var].set(str)
[ドキュメント] def search_files(self, args): """ 概要: 指定された開始パスからファイルパターンに一致するファイルを検索します。 詳細説明: 検索されたファイルパスのリストを'##'で連結した文字列として指定された変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素が検索対象のファイルパターン、 三番目の要素が検索開始パス。 :type args: list of str """ tkvars = self.get_tkvars_dict() varname = args[0] target_file = args[1] start_path = args[2] path_list = find_files(target_file, start_dir = start_path) self.set_var(varname, '##'.join(path_list), set_env = False)
[ドキュメント] def search_latest_file(self, args): """ 概要: 指定された開始パスからファイルパターンに一致する最新のファイルを検索します。 詳細説明: 検索された最新のファイルパスを、指定された変数に設定します。 引数: :param args: 最初の要素が結果を格納する変数名、二番目の要素が検索対象のファイルパターン、 三番目の要素が検索開始パス。 :type args: list of str """ tkvars = self.get_tkvars_dict() varname = args[0] target_file = args[1] start_path = args[2] path = find_latest_file(target_file, start_dir = start_path, defval = None) # print("set", varname, path) self.set_var(varname, path, set_env = False)
[ドキュメント] def choose_if_not_exist(self, args): """ 概要: 指定されたファイルが存在しない場合、ファイル選択ダイアログを表示してユーザーに選択を促します。 詳細説明: ファイルが選択された場合、そのパスを指定された変数に設定します。 引数: :param args: 最初の要素がパスを格納する変数名、二番目の要素がファイルマスク、 三番目の要素がダイアログのタイトルメッセージ。 :type args: list of str 戻り値: :returns: ファイルが選択された場合1、ユーザーがキャンセルした場合-1。 :rtype: int """ varname = args[0] svars = self.svars vars = svars.get_param_dict() selpath = vars.get(varname, "") # selpath = os.environ.get(varname, "") # print(f"[{selpath}] is given by the variable [{varname}]") fmask = args[1] message = args[2] if selpath is None or not os.path.exists(selpath): ftype = [("Specified", fmask), ("All", "*.*")] selpath = tkinter.filedialog.askopenfilename(filetypes = ftype, initialdir = ".", title = message) if not selpath: return -1 self.set_var(varname, selpath, set_env = False) # print(f"[{selpath}] is set to [{varname}]") return 1
[ドキュメント] def get_open_dir_name(self, args, stop_on_cancel = True): """ 概要: ディレクトリ選択ダイアログを表示し、選択されたディレクトリパスを変数に設定します。 引数: :param args: オプションで最初の要素に初期ディレクトリ、二番目以降の要素にダイアログのタイトル。 :type args: list of str :param stop_on_cancel: Trueの場合、ユーザーがキャンセルすると-1を返します。 :type stop_on_cancel: bool 戻り値: :returns: ディレクトリが選択された場合1、キャンセルされた場合は-1。 :rtype: int """ nargs = len(args) fmask = '*.*' ini_dir = '.' caption = 'Select file to open' if nargs >= 1: ini_dir = args[0] if nargs >= 2: caption = " ".join(args[1:]) # ftype = [("All", "*.*")] ftype = [("Specified", fmask)] # print("args=", fmask, ini_dir, caption, ftype) selpath = tkinter.filedialog.askdirectory(initialdir = ini_dir, title = caption) if not selpath: if stop_on_cancel: return -1 self.set_var('o', "", set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set("") self.set_var('o', selpath, set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set(selpath) return 1
[ドキュメント] def get_open_file_name(self, args, stop_on_cancel = True): """ 概要: ファイルオープンダイアログを表示し、選択されたファイルパスを変数に設定します。 引数: :param args: オプションで最初の要素にファイルマスク、二番目の要素に初期ディレクトリ、 三番目以降の要素にダイアログのタイトル。 :type args: list of str :param stop_on_cancel: Trueの場合、ユーザーがキャンセルすると-1を返します。 :type stop_on_cancel: bool 戻り値: :returns: ファイルが選択された場合1、キャンセルされた場合は-1。 :rtype: int """ nargs = len(args) fmask = '*.*' ini_dir = '.' caption = 'Select file to open' if nargs >= 1: fmask = args[0] if nargs >= 2: ini_dir = args[1] if nargs >= 3: caption = " ".join(args[2:]) # ftype = [("All", "*.*")] ftype = [("Specified", fmask), ("All", "*.*")] # print("args=", fmask, ini_dir, caption, ftype) selpath = tkinter.filedialog.askopenfilename(filetypes = ftype, initialdir = ini_dir, title = caption) if not selpath: if stop_on_cancel: return -1 self.set_var('o', "", set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set("") self.set_var('o', selpath, set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set(selpath) return 1
[ドキュメント] def get_save_file_name(self, args, stop_on_cancel = True): """ 概要: ファイル保存ダイアログを表示し、選択された保存ファイルパスを変数に設定します。 引数: :param args: オプションで最初の要素にファイルマスク、二番目の要素に初期ディレクトリ、 三番目以降の要素にダイアログのタイトル。 :type args: list of str :param stop_on_cancel: Trueの場合、ユーザーがキャンセルすると-1を返します。 :type stop_on_cancel: bool 戻り値: :returns: ファイルが選択された場合1、キャンセルされた場合は-1。 :rtype: int """ nargs = len(args) fmask = '*.*' ini_dir = '.' caption = 'Select file to save' if nargs >= 1: fmask = args[0] if nargs >= 2: ini_dir = args[1] if nargs >= 3: caption = " ".join(args[2:]) # ftype = [("All", "*.*")] ftype = [("Specified", fmask)] selpath = tkinter.filedialog.asksaveasfilename(filetypes = ftype, initialdir = ini_dir, title = caption) if not selpath: if stop_on_cancel: return -1 self.set_var('o', "", set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set("") self.set_var('o', selpath, set_env = False) tkvars = self.get_tkvars_dict() tkvars['sel_file'].set(selpath) return 1
[ドキュメント] def move_top(self, f = True): """ 概要: アプリケーションのメインウィンドウを常に最前面に表示するかどうかを設定します。 引数: :param f: Trueの場合、最前面に表示。Falseの場合、通常表示。 :type f: bool """ self.root_window.attributes("-topmost", f)
[ドキュメント] def show_window(self, mode): """ 概要: アプリケーションのメインウィンドウの状態を変更します。 詳細説明: 指定されたモードに応じて、ウィンドウを最小化、最大化、通常表示、非表示、 または最前面表示/解除に切り替えます。 引数: :param mode: ウィンドウの状態を指定する文字列 ('minimize', 'maximize', 'normal', 'hide', 'topmost', 'notopmost')。 :type mode: str """ #Minimize/Maximize/Normal/Hide/TopMost/NoTopMost if mode == 'topmost': self.move_top(True) elif mode == 'notopmost': self.move_top(False) elif mode == 'minimize': self.root_window.iconify() elif mode == 'maximize': # self.root_window.maxsize() self.root_window.state('zoomed') elif mode == 'normal' or mode == 'show': self.root_window.deiconify() elif mode == 'hide': self.root_window.withdraw()
[ドキュメント] def set_window_title(self, title): """ 概要: アプリケーションのメインウィンドウのタイトルを設定します。 引数: :param title: 設定する新しいウィンドウタイトル。 :type title: str """ # print("self.set_window_title", title) self.window_title = title self.root_window.title(title)
[ドキュメント] def set_message(self, message): """ 概要: アプリケーションのステータスバー(またはメッセージ表示領域)にメッセージを設定します。 引数: :param message: 表示するメッセージ。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['message'].set(message)
[ドキュメント] def set_selected_file(self, message): """ 概要: 選択されたファイル名を示す変数にメッセージを設定します。 引数: :param message: 選択されたファイル名または関連メッセージ。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['sel_file'].set(message)
[ドキュメント] def set_command_line(self, message): """ 概要: コマンドライン文字列を示す変数にメッセージを設定します。 引数: :param message: 設定するコマンドライン文字列。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['command_line'].set(message)
[ドキュメント] def set_command_line_org(self, message): """ 概要: 元のコマンドライン文字列を示す変数にメッセージを設定します。 引数: :param message: 設定する元のコマンドライン文字列。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['command_line_org'].set(message)
[ドキュメント] def set_argument(self, message): """ 概要: 引数文字列を示す変数にメッセージを設定します。 引数: :param message: 設定する引数文字列。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['argument'].set(message)
[ドキュメント] def show_message(self, message): """ 概要: アプリケーションのメッセージ表示領域にメッセージを表示します。 引数: :param message: 表示するメッセージ。 :type message: str """ tkvars = self.get_tkvars_dict() tkvars['message'].set(message)