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

使用tkinter制作tkinterUI编辑器


前言

这篇文章继续记录编辑属性的控件。

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

一、EditorPropertyList制作

先上代码,还是EditorPropertyList.py

def collect_font_names():
    """
    获取字体名字
    :return: string
    """
    fonts = ""
    families = tkFont.families()

    for family in families:
        fonts += family + ";"

    PROP_TO_VALUES["font"] = fonts


class EditorPropertyList(ScrollRows):

    def __init__(self, master=None, cnf={}, **kw):
        ScrollRows.__init__(self, master, cnf, **kw)
        self.all_rows = []                              # 存储所有的行
        self.show_rows = []                             # 存储显示的行
        self.row_height = 24                            # 每行的默认高度
        self.editor = None                              # 编辑器
        self.edit_component = None                      # 当前正在编辑的控件对象
        collect_font_names()

    def set_editor(self, editor):
        self.editor = editor

    def set_edit_component(self, edit_component):
        if self.edit_component is edit_component:
            return
        self.edit_component = edit_component

    def on_update(self):
        ScrollRows.on_update(self)
        self.add_prop_rows()

    def get_sorted_rows(self):

        sorted_rows = []
        show_rows_sort = sorted(self.show_rows)
        for row_name in show_rows_sort:
            row = self.get_row_by_name(row_name)
            if row is None:
                continue
            sorted_rows.append(row)

        return sorted_rows

    def calc_slide_window_width(self):

        pos_x = 0

        for child in self.get_sorted_rows():
            if int(child.place_info()["x"]) + child.winfo_reqwidth() > pos_x:
                pos_x = int(child.place_info()["x"]) + child.winfo_reqwidth()

        return pos_x

    def calc_slide_window_height(self):

        pos_y = 0

        for child in self.get_sorted_rows():
            if int(child.place_info()["y"]) + child.winfo_reqheight() > pos_y:
                pos_y = int(child.place_info()["y"]) + child.winfo_reqheight()

        return pos_y

    def get_layout_children(self):
        sorted_children = sorted(self.show_rows, key=lambda x: int(x.split("_")[1]))
        return sorted_children

    def get_row_by_name(self, name):
        """
        根据名字获取row
        :param name: 名字
        :return: row
        """
        return self.get_child_master().children.get("row_" + name, None)

    def add_row(self, label_text, edit_value, edit_type, default_value="None", is_do_layout=True):
        """
        增加一行
        :param label_text:属性名字
        :param edit_value:属性值
        :param edit_type:edit_type
        :param row_values:comboBox的values
        :param is_do_layout:是否do_layout
        :return:None
        """
        prop = {
            "is_show_scroll_x": 0,
            "is_show_scroll_y": 0,
            "is_always_show_scroll": 0,
            "width": self.winfo_reqwidth() - 18,
            "height": self.row_height,
        }

        row = EditorProperty.create_default_property(self.get_child_master(), "row_" + label_text, prop)
        self.add_row_base(row, False)
        row.create_one_property(label_text, edit_value, edit_type, default_value)

        if is_do_layout:
            self.do_layout_row()

        return row

    def add_prop_rows(self):
        """
        创建所有属性的row,如果每次重新创建所有的row会卡,所以在初始化后直接创建
        :return: None
        """
        all_name = sorted(get_all_prop_name())
        for prop_name in all_name:
            edit_type = get_prop_type_by_name(prop_name)
            default_values = PROP_TO_VALUES.get(prop_name, "None")
            self.add_row(prop_name, None, edit_type, default_values, False)
            self.all_rows.append(prop_name)
        self.hide_rows()

    def add_show_rows(self, edit_component, is_update_property=True):
        """
        增加要显示的row
        :param edit_component: 编辑控件
        :param is_update_property: 是否更新属性
        :return: None
        """
        self.set_edit_component(edit_component)
        self.hide_rows()

        prop = {"component_name": ""}
        if int(edit_component.component_info.get("is_main", 0)) == 1:
            prop["is_main"] = 1

        gui_type = edit_component.component_info.get("gui_type", "None")
        for prop_name in get_default_component_info(gui_type, prop).keys():
            self.show_rows.append(prop_name)

        self.do_layout_row()
        if is_update_property:
            self.update_property(edit_component.component_info)

    def hide_rows(self):
        """
        隐藏所有row
        :return: None
        """
        del self.show_rows[:]
        for row_name in self.all_rows:
            row = self.get_row_by_name(row_name)
            if row is None:
                print("hide_rows error row:" + row_name)
                continue
            row.clear_edit_value()
            row.place_forget()
        self.do_layout_row()

    def update_property(self, component_info, prop_list=None):
        """
        更新属性
        :param component_info: 控件信息
        :param prop_list: 要更新的属性列表
        :return: None
        """
        if prop_list is None:
            prop_list = self.show_rows

        for prop_name in prop_list:
            if prop_name not in self.show_rows:
                continue
            if prop_name not in component_info:
                continue
            row = self.get_row_by_name(prop_name)
            if not row:
                continue
            row.update_prop_value(component_info[prop_name])

说明:

  1. collect_font_names函数用来收集系统字体,编辑字体属性的时候直接可以从下拉列表里选择,这个函数放在了EditorPropertyList的初始化函数里调用是因为这个时候tkinter.font已经初始化好,tkinter.font还没初始化好就调用的化会报错
  2. 控件初始化后就把所有的属性编辑框创建出来了,如果每次选中要编辑的控件时进行清除和创建的化会比较卡
  3. 重写了ScrollCanvas的calc_slide_window_width与calc_slide_window_height函数,这里计算滚动的时候只计算当前显示的控件
  4. 重写了ScrollRows的get_sorted_rows函数,是为了重新布局的时候只布局当前显示的控件
  5. add_show_rows这个函数在选中要编辑的控件时调用,之后的记录里再说明
  6. 控件最终效果如下,演示的代码就不贴了,之后还得改
    在这里插入图片描述

上一篇记录 下一篇记录

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

archmage199

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

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

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

打赏作者

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

抵扣说明:

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

余额充值