使用tkinter制作tkinterUI编辑器


目录

  • 使用tkinter制作tkinterUI编辑器
  • 前言
  • 一、关于控件创建的管理
  • 二、编辑器第一版
  • 三、当前目录结构



前言

这篇记录继续上一篇的控件创建,添加一个控件创建的管理类,之后添加编辑器的初版代码,让编辑器能够运行起来



一、关于控件创建的管理

先上代码,componentMgr.py

#!/usr/bin/python
# -*- coding: utf-8 -*-

from components import create_component_from_dict
from toolXmlParser import ToolXmlParser


class componentMgr:

    def __init__(self, master):
        self.master = master
        self.xml_parser = ToolXmlParser()

    def init_main_frame(self, master, component_info, first_child):
        """
        初始化主界面
        :param master: parent
        :param component_info: 控件信息
        :param first_child: 首个孩子
        :return: None
        """
        # 设置标题
        master.title(component_info["title"])

        # 设置大小与位置
        width = component_info["width"]
        height = component_info["height"]
        pos_x = component_info["x"]
        pos_y = component_info["y"]

        master.geometry("%sx%s+%s+%s" % (width, height, pos_x, pos_y))
        first_child.place(x=0, y=0, anchor=component_info["anchor"])

    def create_component_by_info(self, master, component_info, is_init_main, on_create_success=None):
        """
        创建控件by控件信息
        :param master: parent
        :param component_info: 控件信息
        :param is_init_main: 是否是初始化主界面时调用的
        :param on_create_success: 创建成功回调
        :return: 控件
        """
        gui_type = component_info.get("gui_type", "None")
        if gui_type == "None":
            return None

        # 创建控件
        component = create_component_from_dict(master, component_info)

        # 初始化主界面
        is_main = component_info.get("is_main", 0)
        if is_main == "1" and is_init_main:
            self.init_main_frame(master, component_info, component)

        if on_create_success:
            on_create_success(component, component_info, master)

        # 创建children
        for child in component_info.get("children", ()):
            if component == None:
                print("create_component error component=" + child["component_name"])
                continue
            master2 = component.get_child_master() if hasattr(component, "get_child_master") else component
            self.create_component_by_info(master2, child, is_init_main, on_create_success)

        return component

    def load_from_xml(self, master, gui_path, is_init_main=False, on_create_success=None):
        """
        从xml中读取并创建ui
        :param master: 在这个控件创建
        :param gui_path: 文件名称
        :param is_init_main: 是否初始化主界面
        :param on_create_success: 创建成功回调
        :return: Dict
        """
        components = self.xml_parser.load_xml_to_dict(gui_path)
        for parent_name, component_info in components.items():
            self.create_component_by_info(master, component_info, is_init_main, on_create_success)

        return components

    def saves(self, file_name, component_info):
        """
        将ui存入xml文件
        :param file_name: 文件名字(包括路径)
        :param component_info: 控件信息
        :return: None
        """
        self.xml_parser.write_dict_to_xml(file_name, component_info, "root")

说明:

  1. init_main_frame进行主界面的处理,xml中is_main字段用来控制是否是主界面,主界面需要设置标题,坐标以及大小
  2. load_from_xml函数从xml中读取UI并且进行创建,这个函数如果是初始化的时候调用的话才会进行主界面设置,不是初始化的时候调用的话只会把UI创建到指定的父控件里面
  3. create_component_by_info这个函数递归的去创建所有控件,函数中的get_child_master还是为了我自己写的控件而加的特殊逻辑,以后会进行说明
  4. saves函数将控件信息存储到xml中

二、编辑器第一版

先上代码,tkinterEditor.py

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os

from tkinter import Tk
from componentMgr import componentMgr


class tkinterEditor(componentMgr):

    def __init__(self, master, gui_path):
        componentMgr.__init__(self, master)
        self.load_from_xml(master, gui_path, True)

def main():
    root = Tk()
    root.resizable(0, 0)
    path = os.path.join(os.getcwd(), "tkinterEditor.xml")
    tkinterEditor(root, path)
    root.mainloop()


if __name__ == "__main__":
    main()

说明:

  1. 编辑器继承componentMgr类,初始化直接调用load_from_xml读取并创建UI
  2. 因为所有控件都是用place进行显示的,所以我不希望主界面可以调整大小,使用root.resizable(0, 0)进行限制

三、当前目录结构

python 動態生成tkinter按鈕_tkinter


说明:

  1. tkinterEditor.xml就是第一篇记录里面的demo.xml
  2. tkinterEditor.bat是我为了快速启动加的,不用管
  3. 有了这些文件之后运行tkinterEditor.py就能够运行第一版编辑器了,如下图:

python 動態生成tkinter按鈕_python_02