Bootstrap

Python tk GUI工具集成分享

由于用python写了很多小工具,放在各个角落太乱,所以写了一个GUI工具把他们集成起来,有说明,这样使用起来也比较方便


这一页可以分一个大组
在这里插入图片描述
这里可以更新一个小组,点击后直接执行功能函数
在这里插入图片描述
将函数所需要参数,变量放到左上输入,然后提交就可以在右边实时打印脚本print输出
在这里插入图片描述
在这里插入图片描述
如果有新功能,可以在下面添加,当然大家可以按照自己喜好去改

代码:

# coding=utf-8
'''
Ver 1.0.1, 2024-12-10, Hydra
add new function
Get the drop situation of io during firmware upgrade process


'''

script_ver = '1.0.1'
import sys
import os
import re
import os.path
import glob
import ctypes
import subprocess
import linecache
import numpy as np
import threading
import time
import inspect
import traceback

try:
    import tkinter as tk
    from tkinter import ttk
    from tkinter import messagebox
    from tkinter import scrolledtext
except:
    subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'tk'])
    import tkinter as tk
    from tkinter import ttk
    from tkinter import messagebox
    from tkinter import scrolledtext


class function1:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def start(self):
        print('This is function1 %s' % self.kwargs)

class function2:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def start(self):
        print('This is function3 %s' % self.kwargs)

class function3:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def start(self):
        print('This is function3 %s' % self.kwargs)


class FunctionSelector:
    def __init__(self, root, options, readme_info=None):
        self.root = root
        self.options = options
        self.selected_option = None
        self.create_widgets()
        self.info_texts = readme_info if readme_info else {}

    def create_widgets(self):
        self.clear_widgets()
        self.frame = ttk.Frame(self.root, padding="20")
        self.frame.pack(expand=True)

        self.label = ttk.Label(self.frame, text="Please click on the function you want to execute",
                               font=("Helvetica", 16))
        self.label.pack(pady=10)

        select_n = 1
        for key, value in self.options.items():
            button_frame = ttk.Frame(self.frame)
            button_frame.pack(fill=tk.X, padx=10, pady=5)

            button = tk.Button(button_frame, text=f'{select_n}. {value}',
                               command=lambda opt=key: self.on_option_click(opt), anchor="w")
            button.pack(side=tk.LEFT, fill=tk.X, expand=True)

            info_button = tk.Button(button_frame, text="ReadMe", command=lambda opt=key: self.show_info(opt))
            info_button.pack(side=tk.RIGHT)

            select_n += 1

    def show_info(self, option):
        info_text = self.info_texts.get(option, "No information available.")
        messagebox.showinfo("Script Description", info_text)

    def on_option_click(self, option):
        self.selected_option = option
        self.clear_widgets()
        self.root.quit()

    def clear_widgets(self):
        for widget in self.root.winfo_children():
            widget.destroy()

    def get_selected_option(self):
        return self.selected_option


class TextRedirector:
    def __init__(self, text_widget):
        self.text_widget = text_widget

    def write(self, string):
        self.text_widget.insert(tk.END, string)
        self.text_widget.see(tk.END)


class DistributionFunction:
    def __init__(self, root, func, parameter_set):
        self.root = root
        self.func = func
        self.func_result = ''
        self.parameter_set = parameter_set

        main_frame = ttk.Frame(root)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 分割root窗口
        self.left_frame = ttk.Frame(main_frame)
        self.left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        self.right_frame = ttk.Frame(main_frame)
        self.right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

        # 左边分为上下两份
        self.left_top_frame = ttk.Frame(self.left_frame)
        self.left_top_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        self.separator = ttk.Separator(self.left_frame, orient='horizontal')
        self.separator.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)

        self.bottom_left_frame = tk.Frame(self.left_frame)
        self.bottom_left_frame.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

        self.log_text = scrolledtext.ScrolledText(self.right_frame, wrap=tk.WORD)
        self.log_text.pack(fill=tk.BOTH, expand=True)

        self.submit_button = ttk.Button(self.left_top_frame, text="Submit", command=self.submit)
        self.submit_button.pack(side=tk.TOP, anchor='e', padx=5, pady=5)

        self.status_button = ttk.Button(self.bottom_left_frame, text="Execution Status", state='disabled')
        self.status_button.pack(pady=5)

        self.exit_button = tk.Button(self.bottom_left_frame, text="Quit The Window", command=self.root.quit)
        self.exit_button.pack(pady=5)

    def display_dict(self):
        for widget in self.left_top_frame.winfo_children():
            if isinstance(widget, ttk.Entry) or isinstance(widget, ttk.Label):
                widget.destroy()
        self.entries = {}
        input_dict = self.parameter_set[self.func]
        for prompt, default in input_dict.items():
            frame = ttk.Frame(self.left_top_frame)
            frame.pack(fill=tk.X, padx=5, pady=5)
            label = ttk.Label(frame, text=prompt)
            label.pack(side=tk.LEFT)
            entry = ttk.Entry(frame)
            entry.insert(0, default)
            entry.pack(side=tk.RIGHT, fill=tk.X, expand=True)
            self.entries[prompt] = entry
        self.submit_button.pack(side=tk.BOTTOM, anchor='e', padx=5, pady=5)

    def submit(self):
        input_values = {key: entry.get() for key, entry in self.entries.items()}
        self.status_button.config(text="Please wait a moment ...", state='normal')
        threading.Thread(target=self.execute_function, args=(input_values,)).start()

    def execute_function(self, input_values):
        import sys
        sys.stdout = TextRedirector(self.log_text)
        time.sleep(1)
        try:
            execution_func = globals()[self.func]
            self.func_result = execution_func(**input_values).start()
        except Exception as err:
            print(err)
            print(traceback.format_exc())

        if self.func_result:
            self.status_button.config(text="Click Here To Open The Report", state='normal', command=self.open_report)
        else:
            self.status_button.config(text="Execution Successfully", state='normal')

    def open_report(self):
        subprocess.run(['start', '', os.path.join(self.func_result[0], self.func_result[1])], shell=True)
        self.root.quit()


if __name__ == '__main__':
    customer_list = {'customer1': 'hydra1', 'customer2': 'hydra2', 'customer3': 'hydra3', 'customer3': 'hydra4'}
    function_list = {'customer1': {'function1': 'This is function 1',
                                   'function2': 'This is function 2',
                                   'function3': 'This is function 3'}}
    parameter_set = {
        'function1': {'path': os.getcwd(), 'parameter2': '', 'parameter3': 'default parameter'},
        'function2': {'path': os.getcwd()},
        'function3': {'path': os.getcwd()}
    }
    readme_info = {
        'function1': r"This is function1,I don't know what it can do",
        'function2': r"This is function2,I don't know what it can do",
        'function3': r"This is function2,I don't know what it can do"}
    root = tk.Tk()
    root.title(f"Version :{script_ver} Author: Hydra")
    root.geometry("1700x700")

    selector = FunctionSelector(root, customer_list)
    root.mainloop()
    customer = selector.get_selected_option()

    function_select = FunctionSelector(root, function_list[customer], readme_info)
    root.mainloop()
    script = function_select.get_selected_option()
    print(script)

    app = DistributionFunction(root, script, parameter_set)
    app.display_dict()
    root.mainloop()
;