【记录】python3 使用tkinter制作tkinterUI编辑器 《十七》

使用tkinter制作tkinterUI编辑器


前言

这篇文章记录一下工程的创建,到这篇为止基本功能就都记录完了,之后有时间会加一些扩展功能。

完整代码已上传到github,可从第一篇记录下载


一、修改tkinterEditor.py

import shutil

class tkinterEditor(componentMgr):

    def __init__(self, master, gui_path):
        componentMgr.__init__(self, master)
        self.config_parser = ToolConfigParser()
        self.config_parser.read("default.ini", encoding="utf-8-sig")
        self.load_from_xml(master, gui_path, True)
        self.theme = EDITOR_THEME_DEFAULT                                       # 主题
        self.right_edit_menu = None                                             # 鼠标右键edit菜单
        self.edit_components = {}                                               # 存储可编辑的控件
        self.selected_component = None                                          # 当前被选中的控件
        self.created_time = 0                                                   # 创建控件时的时间
        self.created_pos_x = 0                                                  # 创建控件时的坐标x
        self.created_pos_y = 0                                                  # 创建控件时的坐标y
        self.is_new_project_show = True                                         # 创建新project界面是否显示
        self.init_frame()

    def init_frame(self):
        """
        初始化ui
        :return: None
        """
        self.init_menu()
        self.init_theme()
        self.init_file_tab_window()
        self.init_property_list()
        self.init_treeview()
        self.init_quick_btn()
        self.init_top_level()

    def new_project(self):
        """
        新项目
        :return: None
        """
        self.change_new_project_ui()

    ##################################################### top level ############################################

    def init_top_level(self):
        """
        初始化top_level
        :return: None
        """
        self.top_level.protocol("WM_DELETE_WINDOW", self.change_new_project_ui)
        self.top_level.resizable(width=False, height=False)
        self.top_level.positionfrom(who="program")
        self.top_level.children.get("btn_browse", None).bind("<Button-1>", self.on_top_level_browse_click)
        self.top_level.children.get("btn_cancel", None).bind("<Button-1>", self.on_top_level_cancel_click)
        self.top_level.children.get("btn_ok", None).bind("<Button-1>", self.on_top_level_ok_click)
        self.change_new_project_ui()

    def change_new_project_ui(self):
        """
        打开关闭new_project界面
        :return: None
        """
        if self.is_new_project_show:
            self.is_new_project_show = False
            self.top_level.withdraw()
            self.top_level.master.master.wm_attributes('-disabled', False)
            return
        self.is_new_project_show = True
        self.top_level.deiconify()
        self.top_level.master.master.wm_attributes('-disabled', True)

    def on_top_level_browse_click(self, event):
        """
        点击browse
        :param event: event
        :return: None
        """
        location = askdirectory()
        if not location:
            return

        self.entry_location.delete(0, "end")
        self.entry_location.insert(0, location)

    def on_top_level_cancel_click(self, event):
        """
        点击取消
        :param event: event
        :return: None
        """
        self.change_new_project_ui()
        self.top_level.master.master.deiconify()

    def on_top_level_ok_click(self, event):
        """
        点击ok
        :param event: event
        :return: None
        """
        # 获取项目名
        name = self.entry_name.get()
        if not name:
            print("must insert name")
            return

        # 获取项目目录
        location = self.entry_location.get()
        if not location:
            print("must insert location")
            return

        # 创建项目文件夹
        new_path = os.path.join(location, name)
        os.mkdir(new_path)

        # 创建py文件
        self.create_project_py(new_path, name)

        # 拷贝文件
        self.copy_file(new_path)

        # 创建gui文件
        file_path = os.path.join(new_path, name)
        self.new_gui(file_path, None, "frame_" + name)

        # 关闭界面
        self.change_new_project_ui()
        self.top_level.master.master.deiconify()

    def create_project_py(self, file_path, file_name):
        """
        创建py文件
        :param file_path:文件夹路径
        :param file_name:文件名字
        :return:None
        """
        self.create_init_py(file_path)
        self.create_main_py(file_path, file_name)

    @staticmethod
    def create_init_py(file_path):
        """
        创建init.py
        :param file_path:文件夹路径
        :return:None
        """
        file_name = os.path.join(file_path, "init.py")
        with open(file_name, 'w', encoding='utf-8') as f:
            f.write("# -*- coding: UTF-8 -*-\n")

    @staticmethod
    def create_main_py(file_path, name):
        """
        创建main.py
        :param file_path:文件夹路径
        :param name:文件名字
        :return:None
        """
        file_name = os.path.join(file_path, name + ".py")
        with open(file_name, 'w', encoding='utf-8') as f:
            f.write(
                "# -*- coding: UTF-8 -*-\n\n"
                "import os\n"
                "from tkinter import *\n"
                "from componentMgr import componentMgr\n\n\n"
                "class {0}(componentMgr):\n\n"
                "    def __init__(self, master, gui_path):\n"
                "        componentMgr.__init__(self, master)\n"
                "        self.load_from_xml(master, gui_path, True)\n\n\n"
                "def main():\n"
                "    root = Tk()\n"
                "    path = os.path.join(os.getcwd(), '{1}.xml')\n"
                "    {2}(root, path)\n"
                "    root.mainloop()\n\n\n"
                "if __name__ == \"__main__\":\n"
                "    main()\n".format(name, name, name)
            )

    @staticmethod
    def copy_file(file_path):
        """
        拷贝文件
        :param file_path:文件路径
        :return:None
        """
        cur_path = os.getcwd()
        mgr_path = os.path.join(cur_path, "componentMgr.py")
        tool_path = os.path.join(cur_path, "toolXmlParser.py")
        component_path = os.path.join(cur_path, "componentBase.py")
        property_path = os.path.join(cur_path, "componentProperty.py")

        shutil.copy(mgr_path, os.path.join(file_path, "componentMgr.py"))
        shutil.copy(tool_path, os.path.join(file_path, "toolXmlParser.py"))
        shutil.copy(component_path, os.path.join(file_path, "components.py"))
        shutil.copy(property_path, os.path.join(file_path, "componentProperty.py"))

说明:

  1. 导入shutil用于复制文件

  2. change_new_project_ui函数用于打开与关闭创建工程界面

  3. 新加一个componentBase.py用于拷贝,新创建的工程不需要导入我自己加的控件,代码如下:

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    import componentProperty
    
    from tkinter import *
    from tkinter.ttk import Combobox, Treeview, Separator, Progressbar
    from componentProperty import update_all_property, get_default_component_info
    
    
    def create_component_from_dict(master, component_info):
        """
        根据字典里面给定的属性创建控件
        :param master: 父控件
        :param component_info: 控件信息
        :return: 创建的控件
        """
        gui_type = component_info["gui_type"]
        class_name = getattr(sys.modules[__name__], gui_type)
    
        component = class_name(master, name=component_info["component_name"])
        update_all_property(component, component_info, gui_type)
    
        return component
    
    
    def create_default_component(master, component_type, component_name, prop=None, use_name=True):
        """
        创建默认控件
        :param master: 父控件
        :param component_type: 控件类型
        :param component_name: 控件名字
        :param prop: 需要更新的属性
        :param use_name: 是否使用控件名字
        :return: 控件
        """
        class_name = getattr(sys.modules[__name__], component_type)
        if use_name:
            component = class_name(master, name=component_name)
        else:
            component = class_name(master)
    
        component_info = get_default_component_info(component_type, prop)
        update_all_property(component, component_info, component_type)
    
        return component, component_info
    

上一篇记录 下一篇记录

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

archmage199

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值