使用tkinter制作tkinterUI编辑器
前言
这篇文章继续记录编辑属性的控件。
一、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])
说明:
- collect_font_names函数用来收集系统字体,编辑字体属性的时候直接可以从下拉列表里选择,这个函数放在了EditorPropertyList的初始化函数里调用是因为这个时候tkinter.font已经初始化好,tkinter.font还没初始化好就调用的化会报错
- 控件初始化后就把所有的属性编辑框创建出来了,如果每次选中要编辑的控件时进行清除和创建的化会比较卡
- 重写了ScrollCanvas的calc_slide_window_width与calc_slide_window_height函数,这里计算滚动的时候只计算当前显示的控件
- 重写了ScrollRows的get_sorted_rows函数,是为了重新布局的时候只布局当前显示的控件
- add_show_rows这个函数在选中要编辑的控件时调用,之后的记录里再说明
- 控件最终效果如下,演示的代码就不贴了,之后还得改