使用tkinter制作tkinterUI编辑器
前言
这篇文章记录一下控件的创建以及删除,保存ui,菜单里的编辑菜单逻辑,tkinterEditor.py先导入一下time和messagebox。
一、控件的创建
修改tkinterEditor.py
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.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()
def init_quick_btn(self):
"""
初始化功能快捷按键
:return: None
"""
prop = {"y": 5, "activebackground": "red", "borderwidth": 3, "width": 0,}
for quick_name in self.config_parser.options("quick_btn"):
gui_name = self.config_parser.get("quick_btn", quick_name)
prop.update({"text": quick_name})
btn = self.quick_list.add_col(prop, False)
btn.bind("<Button-1>", partial(self.on_quick_btn_click, quick_name, gui_name))
self.quick_list.do_layout_col()
def on_quick_btn_click(self, quick_name, gui_name, event):
"""
点击快捷键
:param gui_name:模块名
:return:None
"""
self.create_control(quick_name, gui_name)
def create_control(self, quick_name, gui_name):
"""
创建控件
:param quick_name: 快捷按钮名字
:param gui_name: 控件名字
:return: None
"""
if self.get_selected_component() is None:
return
child_master = self.get_selected_component().component.get_child_master()
if time.time() - self.created_time > 2:
self.created_pos_x = 0
self.created_pos_y = 0
control_name = self.create_random_name(gui_name)
prop = {
"background": "white", "x": self.created_pos_x, "y": self.created_pos_y,
"component_name": control_name, "gui_type": gui_name,
}
if child_master["background"]== "white":
prop["background"] = "grey"
# 创建一个frame套在真正的控件外面
frame_prop = {
"background": child_master["background"],
}
frame, info = create_default_component(child_master, "Frame", "None", frame_prop, False)
# 创建控件
component, property_dict = create_default_component(frame, gui_name, control_name, prop)
frame.configure(width=component.winfo_reqwidth() + 4, height=component.winfo_reqheight() + 4)
# 以下控件需要重新修改宽和高
if gui_name in ("Progressbar", "Scrollbar"):
frame.configure(width=int(property_dict["width"]) + 4, height=int(property_dict["height"]) + 4)
frame.place_configure(x=property_dict["x"], y=property_dict["y"], anchor=property_dict["anchor"])
component.place_configure(x=0, y=0, anchor="nw")
self.on_component_create(self.file_tab_window.get_cur_tab(), True, component, property_dict, child_master)
self.created_time = time.time()
self.created_pos_x += 10
self.created_pos_y += 10
修改componentEdited.py
def add_child(self, edit_component, is_quick_create):
"""
增加child
:param edit_component: editComponent
:param is_quick_create: 是否是从功能快捷键创建的
:return: None
"""
self.children.append(edit_component)
if is_quick_create:
self.component_info.setdefault("children", []).append(edit_component.get_component_info())
self.editor.treeview.add_node(self.name, edit_component.name, edit_component, END, edit_component.name)
self.editor.treeview.tree.item(self.name, open=True)
二、控件的删除
修改tkinterEditor.py
def delete_control(self):
"""
删除控件
:return:None
"""
cur_tab = self.file_tab_window.get_cur_tab()
if cur_tab is None:
return
edit_component = self.get_selected_component()
if edit_component is None:
return
edit_component.delete_self()
修改componentEdited.py
def delete_self(self):
"""
删除自己
:return: None
"""
if int(self.get_component_info().get("is_main", 0)) == 1:
return
parent_info = self.parent.get_component_info()
if parent_info != None:
parent_info["children"].remove(self.component_info)
master = self.component.master
self.component.destroy()
master.destroy()
self.editor.treeview.tree.delete(self.name)
self.component = None
self.component_info = None
self.component_master = None
self.parent.children.remove(self)
self.editor.on_edit_component_selected(self.parent, False, None)
三、菜单里的编辑菜单
修改tkinterEditor.py
def move_control(self, keysym, event):
"""
移动控件
:param keysym:Up,Down,Left,Right
:return:None
"""
edit_component = self.get_selected_component()
if edit_component is None:
return
pos_x = int(edit_component.component_info["x"])
pos_y = int(edit_component.component_info["y"])
if keysym == "Up":
edit_component.update_property({"y": pos_y - 1})
elif keysym == "Down":
edit_component.update_property({"y": pos_y + 1})
elif keysym == "Left":
edit_component.update_property({"x": pos_x - 1})
else:
edit_component.update_property({"x": pos_x + 1})
def move_up(self):
"""
向上移动控件
:return: None
"""
self.move_control("Up", None)
def move_down(self):
"""
向下移动控件
:return: None
"""
self.move_control("Down", None)
def move_left(self):
"""
向左移动控件
:return: None
"""
self.move_control("Left", None)
def move_right(self):
"""
向右移动控件
:return: None
"""
self.move_control("Right", None)
四、保存xml
修改tkinterEditor.py
def save_gui(self):
"""
保存ui文件
:return: None
"""
cur_tab = self.file_tab_window.get_cur_tab()
if cur_tab is None:
return None
data = self.file_tab_window.get_data(cur_tab)
if not data:
return None
self.saves(data["path"], self.edit_components[data["path"]].get_component_info())
messagebox.showinfo(title='提示', message='保存成功')
def save_as(self):
"""
另存为
:return: None
"""
cur_tab = self.file_tab_window.get_cur_tab()
if cur_tab is None:
return None
data = self.file_tab_window.get_data(cur_tab)
if not data:
return None
file_path = asksaveasfilename(title=u"选择文件", filetypes=[("xml files", "xml"), ])
if not file_path:
return
if not file_path.endswith(".xml"):
file_path += ".xml"
self.saves(file_path, self.edit_components[data["path"]].get_component_info())
messagebox.showinfo(title='提示', message='保存成功')