diff --git a/FractalTree_copy.py b/FractalTree_copy.py new file mode 100644 index 0000000..0823d01 --- /dev/null +++ b/FractalTree_copy.py @@ -0,0 +1,408 @@ +# encoding: utf-8 +from tkinter import * +from tkinter import messagebox + +from PIL import Image, ImageTk +import math +from time import sleep + +from dbUtil import DbUtil + + +class Message(Canvas): + # todo: 日志消息类 + def __init__(self, master, **kwargs): + super().__init__(master, **kwargs) + self.message = [] + self.master = master + self.scrollbar = Scrollbar(master, orient="vertical", command=self.yview) + self.scrollbar.pack(side="right", fill=BOTH) + self.config(yscrollcommand=self.scrollbar.set) + + def show_message(self, message, color="white"): + # todo: 添加日志消息 + self.message.append({"message": message, "color": color}) + num = 0 + self.delete("message") + for function in self.message: + self.create_text(20, 25 * num + 10, anchor="nw", text=function["message"], font=("", 15), fill=function["color"], tags="message") + num += 1 + self.update() + self.configure(scrollregion=self.bbox("all")) + self.scrollbar.set(1.0, 1.0) + self.yview_moveto(1.0) + + +class AddFractal(Toplevel): + def __init__(self, master, _type, fractal_id=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.transient(root) + self.master = master + self.type = _type + self.fractal_id = fractal_id + self.cv = Canvas(self, width=screen_width * 0.5, height=screen_height * 0.7) + self.cv.place(x=0, y=0, anchor=NW) + self.label_width, self.label_height = 140, 40 + self.top_window_back_img = ImageTk.PhotoImage( + Image.open("./images/大背景@3x.jpg").resize((int(screen_width * 0.5), int(screen_height * 0.7)))) + self.save_img = ImageTk.PhotoImage(Image.open("./images/保存@3x.png").resize((100, self.label_height))) + self.update_img = ImageTk.PhotoImage(Image.open("./images/修改@3x.png").resize((100, self.label_height))) + self.add_var_img = ImageTk.PhotoImage(Image.open("./images/添加变量@3x.png").resize((100, self.label_height))) + self.cv.create_image(0, 0, image=self.top_window_back_img, anchor=NW) + self.var_data_dict = {} + self.init_window() + if self.type == "update": + self.load_fractal_data() + + def load_fractal_data(self): + fractal = DbUtil.query_fractal_by_id(self.fractal_id).iloc[0] + self.fractal_name.insert(0, str(fractal["name"])) + self.fractal_e_name.insert(0, str(fractal["e_name"])) + self.basic_pattern.insert(0.0, "\n".join(str(fractal["basic_pattern"]).split("\n")[:-1])) + self.function_code.insert(0.0, "\n".join(str(fractal["function_code"]).split("\n")[:-1])) + self.basic_execute_function.insert(0, str(fractal["basic_pattern"]).split("\n")[-1]) + self.function_code_execute_function.insert(0, str(fractal["function_code"]).split("\n")[-1]) + fractal_var = DbUtil.query_fractal_var_by_id(self.fractal_id) + for i in fractal_var.itertuples(index=False): + self.var_tree.insert("end", f"{i[2]} : {i[0]} = {i[1]}") + + def create_label(self, x, y, img, label_text, entry_width=200): + self.cv.create_image(x, y, image=img, anchor=NW) + self.cv.create_text(x + self.label_width / 2, y + self.label_height / 2, text=label_text, font=("黑体", 12), + fill="black") + entry = Entry(self.cv, font=("Arial", 18, "bold")) + entry.place(x=x + self.label_width, y=y, width=entry_width, height=40, anchor=NW) + return entry + + def add_var(self): + """ + todo: 添加一个变量 + :return: + """ + fractal_comment = self.fractal_comment.get() + fractal_var_name = self.fractal_var_name.get() + fractal_var_value = self.fractal_var_value.get() + if fractal_var_name.strip() == "" and fractal_var_value.strip() == "" and fractal_comment.strip() == "": + messagebox.showwarning("提示", "变量名称,变量注释和变量值不能为空!") + return + if fractal_var_name in self.var_data_dict: + messagebox.showerror("提示", "该变量已经存在!") + self.fractal_comment.delete(0, "end"), self.fractal_var_name.delete(0, "end"), self.fractal_var_value.delete(0, "end") + return + self.var_data_dict[fractal_var_name] = (fractal_comment, fractal_var_value) + self.var_tree.insert("end", f"{fractal_comment} : {fractal_var_name} = {fractal_var_value}") + self.fractal_comment.delete(0, "end"), self.fractal_var_name.delete(0, "end"), self.fractal_var_value.delete(0, "end") + + def save(self): + fractal_name = self.fractal_name.get() + fractal_e_name = self.fractal_e_name.get() + basic_execute_function = self.basic_execute_function.get() + function_code_execute_function = self.function_code_execute_function.get() + function_code = self.function_code.get(0.0, "end") + basic_pattern = self.basic_pattern.get(0.0, "end") + if fractal_name.strip() == "" \ + and fractal_e_name == "" \ + and basic_execute_function.strip() == ""\ + and basic_pattern.strip() == ""\ + and function_code.strip() == ""\ + and function_code_execute_function.strip() == "": + messagebox.showwarning("提示", "值不能为空!") + return + function_code = function_code + "\n" + function_code_execute_function + basic_pattern = basic_pattern + "\n" + basic_execute_function + if self.type == "update": + DbUtil.update_to_fractal(self.fractal_id, fractal_name, fractal_e_name, basic_pattern, function_code) + for key, data in self.var_data_dict.items(): + DbUtil.insert_to_var(key, data[1], data[0], self.fractal_id) + self.master.master.message.show_message("更新成功!") + else: + id = DbUtil.insert_to_fractal(fractal_name, fractal_e_name, basic_pattern, function_code) + for key, data in self.var_data_dict.items(): + DbUtil.insert_to_var(key, data[1], data[0], id) + self.master.master.message.show_message("添加成功!") + self.destroy() + self.master.master.flush() + + def init_window(self): + self.label_img = ImageTk.PhotoImage( + Image.open("./images/文字背景@3x.png").resize((self.label_width, self.label_height))) + self.fractal_name = self.create_label(50, 30, self.label_img, "分形名称") + self.fractal_e_name = self.create_label(50, 30 + self.label_height + 15, self.label_img, "分形英文名称") + self.fractal_comment = self.create_label(50, 30 + (self.label_height + 15) * 2, self.label_img, "变量注释") + self.fractal_var_name = self.create_label(50, 30 + (self.label_height + 15) * 3, self.label_img, "变量名称") + self.fractal_var_value = self.create_label(50, 30 + (self.label_height + 15) * 4, self.label_img, "变量值") + self.basic_execute_function = self.create_label(50, 30 + (self.label_height + 15) * 5, self.label_img, "基本图案调用函数") + self.function_code_execute_function = self.create_label(50 + 15 + self.label_width + 300 + 30, 30 + (self.label_height + 15) * 5, self.label_img, "分形树调用函数", entry_width=250) + Button(self.cv, image=self.add_var_img, command=self.add_var, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, ).place(x=50 + 15 + self.label_width + 200, y=30 + (self.label_height + 15) * 4, width=100, height=self.label_height, anchor=NW) + Button(self.cv, image=self.save_img if self.type == "add" else self.update_img, command=self.save, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, ).place(x=50 + 15 + self.label_width + 200, y=30 + (self.label_height + 15) * 7 - 15 + 300 - self.label_height, width=100, height=self.label_height, anchor=NW) + list_frame = Frame(self.cv) + list_frame.place(x=50 + 15 + self.label_width + 300 + 30, y=30, height=(self.label_height + 15) * 5 - 15, width=400) + self.var_tree = Listbox(list_frame, font=("Arial", 14), bg="#bce7f7", highlightthickness=0, highlightcolor="#bce7f7") + self.var_tree.pack(side="left", fill="both", expand=True) + scrollbar = Scrollbar(list_frame, command=self.var_tree.yview) + scrollbar.pack(side="right", fill="y") + self.var_tree.config(yscrollcommand=scrollbar.set) + self.basic_label_image = ImageTk.PhotoImage(Image.open("./images/文字背景@3x.png").resize((self.label_width + 200, 30))) + self.cv.create_image(50, (self.label_height + 15) * 7 - 15, image=self.basic_label_image, anchor=NW) + self.cv.create_text(50 + (self.label_width + 200) / 2, (self.label_height + 15) * 7, text="基本图案绘制函数", font=("黑体", 14)) + self.basic_pattern = Text(self.cv, font=("Arial", 14), bg="#bce7f7", highlightthickness=0,) + self.basic_pattern.place(x=50, y=(self.label_height + 15) * 7 + 15, width=self.label_width + 200, height=300) + + self.function_code_label_image = ImageTk.PhotoImage(Image.open("./images/文字背景@3x.png").resize((400, 30))) + self.cv.create_image(50 + 15 + self.label_width + 300 + 30, (self.label_height + 15) * 7 - 15, image=self.function_code_label_image, anchor=NW) + self.cv.create_text(50 + 15 + self.label_width + 300 + 30 + 400 / 2, (self.label_height + 15) * 7, text="分形树绘制函数", + font=("黑体", 14)) + self.function_code = Text(self.cv, font=("Arial", 14), bg="#bce7f7", highlightthickness=0, ) + self.function_code.place(x=50 + 15 + self.label_width + 300 + 30, y=(self.label_height + 15) * 7 + 15, width=400, height=300) + + +class SelectFractalFrame(Frame): + # todo: 右上方分形图案单选框类 + def __init__(self, master, *args, ** kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.img = ImageTk.PhotoImage(Image.open("./images/上部背景@3x.png").resize( + (int(self.width), self.height))) + Label(self, width=self.width, height=self.height, image=self.img).place(x=0, y=0, anchor=NW) + Label(self, text="分形图案类型", font=("黑体", 14, "bold"), bg="#f7f7f7", ).place(x=10, y=10) + self.button_img = ImageTk.PhotoImage(Image.open("./images/新增分形图案类型@3x.png").resize((120, 36))) + Button(self, image=self.button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.add_fractal_tree).place(x=280, y=8) + self.update_button_img = ImageTk.PhotoImage(Image.open("./images/修改分形图案@3x.png").resize((120, 36))) + Button(self, image=self.update_button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.update_fractal_tree).place(x=150, y=8) + self.select_frame = Frame(self, width=self.width, height=self.height * 0.8, bg="#f7f7f7") + self.select_frame.place(x=0, y=self.height * 0.2) + self.create_select_menu() + + def add_fractal_tree(self): + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + x, y = int(screen_width - screen_width * 0.5) // 2, int(screen_height - screen_height * 0.6) // 2 + top_window = AddFractal(self, "add", width=screen_width * 0.5, height=screen_height * 0.7) + top_window.geometry(f'{int(screen_width * 0.5)}x{int(screen_height * 0.7)}+{x}+{y}') + top_window.mainloop() + + def update_fractal_tree(self): + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + x, y = int(screen_width - screen_width * 0.5) // 2, int(screen_height - screen_height * 0.6) // 2 + top_window = AddFractal(self, "update", width=screen_width * 0.5, height=screen_height * 0.7, fractal_id=self.master.chose_fractal.get()) + top_window.geometry(f'{int(screen_width * 0.5)}x{int(screen_height * 0.7)}+{x}+{y}') + top_window.mainloop() + + def create_select_menu(self): + # todo: 创建分形图案单选框 + data_frame = self.db.execute("select * from fractal") + yscro = Scrollbar(self.select_frame, orient=VERTICAL) + yscro.place(x=self.width - 20, y=0, height=self.height * 0.8, width=20, anchor='nw') + canvas = Canvas(self.select_frame, width=self.width - 20, height=self.height * 0.8, bg="#f7f7f7") + canvas.place(x=0, y=0, anchor='nw') + f2 = Frame(canvas, bg="#f7f7f7", width=self.width * 0.8, height=self.height * 0.8) + canvas.create_window((0, 0), window=f2, anchor=NW) + self.master.chose_fractal = IntVar() + self.master.chose_fractal.set(data_frame.loc[0:]["id"].tolist()[0]) + for data in data_frame.itertuples(index=False): + f_id, name, e_name, basic_pattern, function_code = data[0], data[1], data[2], data[3], data[4] + Radiobutton(f2, text=f"{name} {e_name}", value=f_id, command=lambda message=f"{name} {e_name}": self.master.update_select(message), + variable=self.master.chose_fractal, font=("", 18), bg="#f7f7f7").pack(ipadx=10, anchor="w") + canvas.update() + canvas.config(scrollregion=canvas.bbox("all"), yscrollcommand=yscro.set) # 设置画布的滚动区域 + yscro.config(command=canvas.yview) + + +class FormFractalFrame(Frame): + # todo: 右下方变量填写类 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.var_dict = {} + self.img = ImageTk.PhotoImage(Image.open("./images/上部背景@3x.png").resize( + (int(self.width), self.height))) + Label(self, width=self.width, height=self.height, image=self.img).place(x=0, y=0, anchor=NW) + Label(self, text="分形参数设置", font=("黑体", 14, "bold"), bg="#f7f7f7", ).place(x=10, y=10) + self.create_form() + self.button_img = ImageTk.PhotoImage(Image.open("./images/基本图案绘制@3x.png").resize((90, 36))) + Button(self, image=self.button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.master.basic_tree_canvas.draw_basic_tree).place(x=10, y=self.height - 50) + self.button2_img = ImageTk.PhotoImage(Image.open("./images/绘制参数更新@3x.png").resize((90, 36))) + Button(self, image=self.button2_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.update_fractal_var).place(x=100 + 5, y=self.height - 50) + self.button3_img = ImageTk.PhotoImage(Image.open("./images/绘制@3x.png").resize((70, 36))) + Button(self, image=self.button3_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.master.fractal_tree_canvas.draw_fractal_tree).place(x=100 * 2 + 5, y=self.height - 50) + self.button4_img = ImageTk.PhotoImage(Image.open("./images/删除图案@3x.png").resize((90, 36))) + Button(self, image=self.button4_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.delete_fractal).place(x=95 * 3, y=self.height - 50) + + def delete_fractal(self): + """ + 删除分形树 + :return: + """ + result = messagebox.askquestion("确认框", "您确定要执行此操作吗?") + if not result == "yes": + return + fractal_id = self.master.chose_fractal.get() + DbUtil.delete_fractal(fractal_id) + self.master.flush() + self.master.message.show_message("删除成功!") + + + def update_fractal_var(self): + # todo: 绘制参数更新 + try: + for key, value in self.var_dict.items(): + sql = "update fractal_var set value='{}' where fractal_id={} and name='{}'".format(value.get(), self.master.chose_fractal.get(), key) + self.db.update(sql) + self.master.message.show_message("参数更新成功!") + except Exception as E: + self.master.message.show_message(f"{E}", "red") + + def create_form(self): + # todo: 分形图案变量生成 + data_frame = self.db.query_fractal_var_by_id(self.master.chose_fractal.get()) + self.select_frame = Frame(self, width=self.width, height=self.height * 0.6, bg="#f7f7f7") + self.select_frame.place(x=0, y=self.height * 0.2) + yscro = Scrollbar(self.select_frame, orient=VERTICAL) + yscro.place(x=self.width - 20, y=0, height=self.height * 0.6, width=20, anchor='nw') + canvas = Canvas(self.select_frame, width=self.width - 20, height=self.height * 0.6, bg="#f7f7f7") + canvas.place(x=0, y=0, anchor='nw') + f2 = Frame(canvas, bg="#f7f7f7", width=self.width * 0.8, height=self.height * 0.6) + canvas.create_window((0, 0), window=f2, anchor=NW) + self.var_dict = {} + for data in data_frame.itertuples(): + index, name, value, comment, value_type = data[0], data[1], data[2], data[3], data[4] + Label(f2, text=f"{comment}:{name}=", width=20, font=("黑体", 14, "bold"), anchor=W, bg="#f7f7f7").grid(row=index, column=0, padx=10, pady=10) + self.var_dict[name] = Entry(f2, font=("黑体", 14, "bold")) + self.var_dict[name].insert(0, value) + self.var_dict[name].grid(row=index, column=1, pady=10) + self.master.message.show_message(f"\t{comment}:{name} = {value}") + canvas.update() + canvas.config(scrollregion=canvas.bbox("all"), yscrollcommand=yscro.set) # 设置画布的滚动区域 + yscro.config(command=canvas.yview) + + +class BasicTree(Canvas): + # todo: 基本图案绘制画布类 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.background_img = ImageTk.PhotoImage(Image.open("./images/全览图@3x.png").resize((self.width + 20, self.height + 20))) + self.create_image(-5, -5, image=self.background_img, anchor=NW) + + def draw_basic_tree(self): + # todo: 绘制基本图案 + self.delete("all") + data_frame = self.db.query_fractal_by_id(self.master.chose_fractal.get()) + params = { + "canvas": self + } + try: + exec(data_frame["basic_pattern"].tolist()[0], params) + self.master.message.show_message(f"基本图案绘制成功!") + except Exception as E: + self.master.message.show_message(f"{E}", color="red") + + +class FractalTreeCanvas(Canvas): + # todo: 绘制分形树画布 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + + def draw_fractal_tree(self): + # todo: 绘制分形树 + try: + self.delete("all") + data_frame = self.db.query_fractal_by_id(self.master.chose_fractal.get()) + fractal_var = self.db.query_fractal_var_by_id(self.master.chose_fractal.get()) + params = {fractal_var["name"].tolist()[i]: eval(fractal_var["value"].tolist()[i]) for i in range(len(fractal_var["name"].tolist()))} + params["canvas"] = self + params["math"] = math + params["sleep"] = sleep + exec(data_frame["function_code"].tolist()[0], params) + self.master.message.show_message("分形树绘制成功!") + except Exception as E: + self.master.message.show_message(f"{E}", "red") + + +class FractalTree(Canvas): + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.background_image = ImageTk.PhotoImage(Image.open("./images/大背景@3x.jpg").resize((self.width, self.height))) + self.create_image(0, 0, image=self.background_image, anchor=NW) + self.chose_fractal = 1 + self.function_code = "" + self.fractal_var = {} + self.init_window() + + def update_select(self, message): + # todo: 切换分形图案 + self.message.show_message(f"选择了{message},参数如下:") + self.form_fractal_frame.create_form() + + def flush(self): + self.select_fractal_frame.create_select_menu() + self.form_fractal_frame.create_form() + + def init_window(self): + """ + 初始化窗口,创建窗口并布局 + :return: + """ + # 创建下方消息显示框 + message_frame = Frame(self, width=self.width - 60, height=self.height * 0.2) + message_frame.place(x=15, y=self.height * 0.8 + 15, anchor=NW) + self.message = Message(message_frame, width=self.width - 60, height=self.height * 0.2 - 30) + self.message.pack(anchor=NW) + self.message.configure(bg="#85bbd1") + + # 分形树画布 + self.fractal_tree_canvas = FractalTreeCanvas(self, width=self.width * 0.73 - 10, height=self.height * 0.8 + 12, highlightthickness=0, bg="#b5e6f5") + self.fractal_tree_canvas.place(x=0, y=0, anchor=NW) + + # 基本图形绘制框 + self.basic_tree_canvas = BasicTree(self, width=150, height=150, bg="#e0eaf5", bd=0) + self.basic_tree_canvas.place(x=15, y=self.height * 0.8 - 150, anchor=NW) + + # 创建左上方分形图案选择框 + self.select_fractal_frame = SelectFractalFrame(self, width=self.width * 0.27 - 10, height=int((self.height * 0.8) / 2) - 10) + self.select_fractal_frame.place(x=self.width * 0.73, y=10, anchor=NW) + + # 创建左下方输入框 + self.form_fractal_frame = FormFractalFrame(self, width=self.width * 0.27 - 10, height=int((self.height * 0.8) / 2)) + self.form_fractal_frame.place(x=self.width * 0.73, y=self.height * 0.8 / 2 + 10, anchor=NW) + + +if __name__ == '__main__': + # 创建主窗口 + root = Tk() + root.title('分形树') + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + root_attr = { + "width": screen_width * 0.8, + "height": screen_height * 0.8, + } + size = '%dx%d+%d+%d' % (root_attr['width'], root_attr['height'], (screen_width - root_attr['width']) / 2, + (screen_height - root_attr['height']) / 2 - 30) + root.geometry(size) + tree = FractalTree(root, width=root_attr["width"], height=root_attr["height"]) + tree.place(x=0, y=0, anchor=NW) + root.mainloop() + + diff --git a/X24.py b/X24.py index e8e4a62..aa221e5 100644 --- a/X24.py +++ b/X24.py @@ -2,7 +2,7 @@ # 文本分析和图像识别 # 开发时间 2023/7/17 15:52 # 创建主窗口 -import fractaltree +import fractaltree1 import tkinter as tk import tkinter.font as tf @@ -65,7 +65,7 @@ rb_Triangle.pack(anchor='w') rb_Rect = tk.Radiobutton(frame, text="矩形分形 Rect_Fractal", variable=shape_var, value='Rect', bg="white", font=ft1) rb_Rect.pack(anchor='w') -from fractaltree import pd +from fractaltree1 import pd import os if os.path.exists('params.csv'): df=pd.read_csv("params.csv") @@ -98,17 +98,17 @@ cv_small.place(x=0, y=big_height, anchor='sw') params_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") params_text.configure(font=ft3, spacing1=15) params_text.place(x=20, y=300, width=480, height=310, anchor='nw') -from fractaltree import params_Y +from fractaltree1 import params_Y # 初始化分形参数并输出 params_str = params_Y params_text.insert(tk.INSERT, params_str) -from fractaltree import update_Text +from fractaltree1 import update_Text # trace追踪变量w模式,回调函数update_text shape_var.trace('w', lambda *args, str_params_dict=str_params_dict: update_Text()) -from fractaltree import delete_rb -from fractaltree import draw_pattern -from fractaltree import update_params -from fractaltree import draw_tree +from fractaltree1 import delete_rb +from fractaltree1 import draw_pattern +from fractaltree1 import update_params +from fractaltree1 import draw_tree # 创建四个按钮 button_delete = tk.Button(root, text="删除\n选项", command=delete_rb, font=ft2) button_delete.place(x=20, y=700, width=90, height=75, anchor='sw') diff --git a/X35.py b/X35.py index d1a3a30..20fc45c 100644 --- a/X35.py +++ b/X35.py @@ -2,7 +2,7 @@ # 文本分析和图像识别 # 开发时间 2023/7/17 16:40 import math -import fractaltree +import fractaltree1 def run_Y_tree(): # Y形分形树函数 def Y_tree(depth, percent, left_angle, right_angle, start_point, angle, length, canvas): diff --git a/Y.py b/Y.py new file mode 100644 index 0000000..fa45954 --- /dev/null +++ b/Y.py @@ -0,0 +1,34 @@ +def Y_pattern(): + canvas.delete("all") # 清除画布 + canvas.create_line(20, 30, 110, 90, fill='red', width=2) # 左臂 + canvas.create_line(170, 30, 110, 90, fill='red', width=2) # 右臂 + canvas.create_line(80, 160, 80, 90, fill='red', width=2) # 中心线 + + +def Y_tree(depth, percent, left_angle, right_angle, start_point, angle, length, canvas): + if depth == 0: + return + end_point = (start_point[0] + length * math.cos(math.radians(angle)), + start_point[1] - length * math.sin(math.radians(angle))) + canvas.create_line(start_point, end_point, fill=color, width=2) + Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle + right_angle, length * percent, + canvas) # 画右枝 + Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle - left_angle, length * percent, + canvas) # 画左枝 + canvas.update() + sleep(0.001) + + +Y_tree(finishLevel, treePercent, leftAngle, rightAngle, initPoint, initAngle, initLong, canvas) + +Y_pattern() + + +分形层数:finishLevel=10 +缩放比例:treePercent=0.7 +左枝倾角:leftAngle=90 +右枝倾角:rightAngle=180 +初始点:initPoint=(520, 600) +初始角:initAngle=90 +初始长度:initLong=150 +颜色:color="#85bbd1" \ No newline at end of file diff --git a/dbUtil.py b/dbUtil.py new file mode 100644 index 0000000..8757bb3 --- /dev/null +++ b/dbUtil.py @@ -0,0 +1,58 @@ +import pymysql +import pandas as pd + + +conn = pymysql.connect(user="root", password="123123", database="tree", + host="127.0.0.1", port=3306) +class DbUtil(): + + @staticmethod + def insert_to_fractal(name, e_name, basic_pattern, function_code, vars): + sql = """ + insert into fractal(name, e_name, basic_pattern, function_code, vars) values (%s, %s, %s, %s, %s) + """ + cursor = conn.cursor() + cursor.execute(sql, (name, e_name, basic_pattern, function_code, vars)) + conn.commit() + id = cursor.lastrowid + return id + + @staticmethod + def update_to_fractal(fractal_id, name, e_name, basic_pattern, function_code, vars): + sql = """ + update fractal set name=%s, e_name=%s, basic_pattern=%s, function_code=%s, vars=%s where id=%s + """ + cursor = conn.cursor() + cursor.execute(sql, (name, e_name, basic_pattern, function_code, vars, fractal_id)) + conn.commit() + + @staticmethod + def insert_to_var(name, value, comment, fractal_id): + sql = f"insert into fractal_var values ('{name}', '{value}', '{comment}', {fractal_id})" + cursor = conn.cursor() + cursor.execute(sql) + conn.commit() + + @staticmethod + def delete_fractal(id): + conn.cursor().execute(f"delete from fractal_var where fractal_id={id}") + conn.commit() + conn.cursor().execute(f"delete from fractal where id={id}") + conn.commit() + + @staticmethod + def execute(sql): + return pd.read_sql(sql, con=conn) + + @staticmethod + def update(sql): + conn.cursor().execute(sql) + conn.commit() + + @staticmethod + def query_fractal_by_id(id): + return pd.read_sql("select * from fractal where id={}".format(id), con=conn) + + @staticmethod + def query_fractal_var_by_id(id): + return pd.read_sql("select * from fractal_var where fractal_id={}".format(id), con=conn) \ No newline at end of file diff --git a/fractaltree.py b/fractaltree.py index 2039bda..dae6852 100644 --- a/fractaltree.py +++ b/fractaltree.py @@ -1,755 +1,393 @@ -# -*- coding:utf-8 -*- +# encoding: utf-8 +from tkinter import * +from tkinter import messagebox -import tkinter as tk -import tkinter.font as tf +from PIL import Image, ImageTk import math -import pandas as pd -import pymysql -import os - -# Y形分形 Y_Fractal -# 参数初始化 -FinishLevel_Y = 14 -TreePercent_Y = 0.7 -LeftAngle_Y = 30 -RightAngle_Y = 30 -InitPoint_Y = (420, 500) -InitAngle_Y = 90 -InitLong_Y = 150 - -# Y形分形参数的字符串形式输出 -params_Y = " 分形层数:finishLevel={}\n" \ - " 缩放比例:treePercent={}\n" \ - " 左枝倾角:leftAngle={}\n" \ - " 右枝倾角:rightAngle={}\n" \ - " 初始点:initPoint={}\n" \ - " 初始角:initAngle={}\n" \ - " 初始长度:initLong={}".format(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, - InitPoint_Y, InitAngle_Y, InitLong_Y) - - -# Y形基本图案函数 -def yPattern(): - cv_small.delete("all") # 清除画布 - cv_small.create_line(30, 10, 90, 70, fill='red', width=2) # 左臂 - cv_small.create_line(150, 10, 90, 70, fill='red', width=2) # 右臂 - cv_small.create_line(90, 140, 90, 70, fill='red', width=2) # 中心线 - - -# Y形树执行函数 -def run_Y_tree(): - # Y形分形树函数 - def Y_tree(depth, percent, left_angle, right_angle, start_point, angle, length, canvas): - if depth == 0: +from time import sleep + +from dbUtil import DbUtil + + +class Message(Canvas): + # todo: 日志消息类 + def __init__(self, master, **kwargs): + super().__init__(master, **kwargs) + self.message = [] + self.master = master + self.scrollbar = Scrollbar(master, orient="vertical", command=self.yview) + self.scrollbar.pack(side="right", fill=BOTH) + self.config(yscrollcommand=self.scrollbar.set) + + def show_message(self, message, color="white"): + # todo: 添加日志消息 + self.message.append({"message": message, "color": color}) + num = 0 + self.delete("message") + for function in self.message: + self.create_text(20, 25 * num + 10, anchor="nw", text=function["message"], font=("", 15), fill=function["color"], tags="message") + num += 1 + self.update() + self.configure(scrollregion=self.bbox("all")) + self.scrollbar.set(1.0, 1.0) + self.yview_moveto(1.0) + + +class AddFractal(Toplevel): + def __init__(self, master, _type, fractal_id=None, *args, **kwargs): + super().__init__(*args, **kwargs) + self.transient(root) + self.master = master + self.type = _type + self.fractal_id = fractal_id + self.cv = Canvas(self, width=screen_width * 0.65, height=screen_height * 0.8) + self.width, self.height = int(screen_width * 0.65), int(screen_height * 0.8) + self.cv.place(x=0, y=0, anchor=NW) + self.label_width, self.label_height = 140, 40 + self.top_window_back_img = ImageTk.PhotoImage( + Image.open("./images/大背景@3x.jpg").resize((int(screen_width * 0.65), int(screen_height * 0.8)))) + self.save_img = ImageTk.PhotoImage(Image.open("./images/保存@3x.png").resize((100, self.label_height))) + self.update_img = ImageTk.PhotoImage(Image.open("./images/修改@3x.png").resize((100, self.label_height))) + self.cv.create_image(0, 0, image=self.top_window_back_img, anchor=NW) + self.var_data_dict = {} + if self.type == "update": + fractal = DbUtil.query_fractal_by_id(self.fractal_id).iloc[0] + self.is_default = fractal["is_default"] + self.init_window() + if self.type == "update": + self.load_fractal_data() + + def load_fractal_data(self): + fractal = DbUtil.query_fractal_by_id(self.fractal_id).iloc[0] + self.fractal_name.insert(0, str(fractal["name"])) + self.fractal_e_name.insert(0, str(fractal["e_name"])) + self.basic_pattern.insert(0.0, "\n".join(str(fractal["basic_pattern"]).split("\n")[:-1])) + self.function_code.insert(0.0, "\n".join(str(fractal["function_code"]).split("\n")[:-1])) + self.basic_execute_function.insert(0, str(fractal["basic_pattern"]).split("\n")[-1]) + self.function_code_execute_function.insert(0, str(fractal["function_code"]).split("\n")[-1]) + self.var_tree.insert(0.0, "\n".join(str(fractal["vars"]).split("\n")[:-1])) + if self.is_default == 0: + self.fractal_name.config(state="readonly") + self.fractal_e_name.config(state="readonly") + self.basic_pattern.config(state="disabled") + self.basic_execute_function.config(state="readonly") + self.function_code_execute_function.config(state="readonly") + self.var_tree.config(state="disabled") + self.function_code.config(state="disabled") + + + def create_label(self, x, y, img, label_text, entry_width=200): + self.cv.create_image(x, y, image=img, anchor=NW) + self.cv.create_text(x + self.label_width / 2, y + self.label_height / 2, text=label_text, font=("黑体", 12), + fill="black") + entry = Entry(self.cv, font=("Arial", 18, "bold")) + entry.place(x=x + self.label_width, y=y, width=entry_width, height=40, anchor=NW) + return entry + + def save(self): + fractal_name = self.fractal_name.get() + fractal_e_name = self.fractal_e_name.get() + basic_execute_function = self.basic_execute_function.get() + function_code_execute_function = self.function_code_execute_function.get() + function_code = self.function_code.get(0.0, "end") + basic_pattern = self.basic_pattern.get(0.0, "end") + vars = self.var_tree.get(0.0, "end") + if fractal_name.strip() == "" \ + and fractal_e_name == "" \ + and basic_execute_function.strip() == ""\ + and basic_pattern.strip() == ""\ + and function_code.strip() == ""\ + and function_code_execute_function.strip() == "": + messagebox.showwarning("提示", "值不能为空!") return - end_point = (start_point[0] + length * math.cos(math.radians(angle)), - start_point[1] - length * math.sin(math.radians(angle))) - canvas.create_line(start_point, end_point, fill='LightBlue4', width=2) - # canvas.update() - # canvas.after(1) - Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle + right_angle, length * percent, - canvas) # 画右枝 - Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle - left_angle, length * percent, - canvas) # 画左枝 - # print(start_point,end_point) - - # 清除画布 - cv_big.delete("all") - # 将初始参数传入函数 - Y_tree(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, InitAngle_Y, InitLong_Y, cv_big) - output_text.delete("1.0", "end") - # 在底部的结果输出框输出分形树的绘制参数 - text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, treePercent={}," \ - " leftAngle={}, rightAngle={}, initPoint={}, initAngle={}, initLong={}" \ - .format(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, - InitAngle_Y, InitLong_Y) - output_text.insert(tk.INSERT, text) - - -# Y形分形参数更新函数 -def update_params_Y(): - new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 - new_params = new_str.split('\n') - new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 - # 参数更新 - global FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, InitAngle_Y, InitLong_Y - FinishLevel_Y = int(new_params[0]) - TreePercent_Y = float(new_params[1]) - LeftAngle_Y = int(new_params[2]) - RightAngle_Y = int(new_params[3]) - InitPoint_Y = tuple(map(int, new_params[4][1:-1].split(','))) - InitAngle_Y = int(new_params[5]) - InitLong_Y = int(new_params[6]) - - -# 三角形分形 Triangle_Fractal -# 参数初始化 -FinishLevel_tri = 14 -TreePercent_tri = 0.7 -InitPoint_tri = (420, 500) -InitAngle_tri = 30 -InitLong_tri = 170 -params_Triangle = " 分形层数:finishLevel={}\n" \ - " 缩放比例:treePercent={}\n" \ - " 初始点:initPoint={}\n" \ - " 初始角:initAngle={}\n" \ - " 初始长度:initLong={}".format(FinishLevel_tri, TreePercent_tri, InitPoint_tri, - InitAngle_tri, InitLong_tri) - - -# 三角形分形参数设置 -def update_params_Triangle(): - new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 - new_params = new_str.split('\n') - new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 - # 参数更新 - global FinishLevel_tri, TreePercent_tri, InitPoint_tri, InitAngle_tri, InitLong_tri - FinishLevel_tri = int(new_params[0]) - TreePercent_tri = float(new_params[1]) - InitPoint_tri = tuple(map(int, new_params[2][1:-1].split(','))) - InitAngle_tri = int(new_params[3]) - InitLong_tri = int(new_params[4]) - - -# 三角形基本图案函数 -def Triangle_Pattern(): - cv_small.delete("all") # 清除画布 - cv_small.create_polygon(80, 130, 20, 10, 140, 10, outline='red', fill='white', width=2) - - -# 三角形分形树执行函数(倒的坐标系) -def run_Triangle_tree(): - # 三角形分形树函数 - def Triangle_tree(depth, percent, start_point, angle, length, canvas): - if depth == 0: + function_code = function_code + "\n" + function_code_execute_function + basic_pattern = basic_pattern + "\n" + basic_execute_function + if self.type == "update": + DbUtil.update_to_fractal(self.fractal_id, fractal_name, fractal_e_name, basic_pattern, function_code, vars) + self.master.master.message.show_message("更新成功!") + else: + id = DbUtil.insert_to_fractal(fractal_name, fractal_e_name, basic_pattern, function_code, vars) + self.master.master.message.show_message("添加成功!") + self.destroy() + self.master.master.flush() + + def init_window(self): + self.label_img = ImageTk.PhotoImage( + Image.open("./images/文字背景@3x.png").resize((self.label_width, self.label_height))) + self.fractal_name = self.create_label(35, 30, self.label_img, "分形名称", int((self.width - 100) / 2 - 140)) + self.fractal_e_name = self.create_label(35 + int((self.width - 100) / 2) + 30, 30, self.label_img, "分形英文名称", int((self.width - 100) / 2 - 140)) + + self.basic_execute_function = self.create_label(35, 30 + (self.label_height + 15) * 1, self.label_img, "基本图案调用函数", int((self.width - 100) / 2 - 140)) + self.function_code_execute_function = self.create_label(35 + int((self.width - 100) / 2) + 30, 30 + (self.label_height + 15) * 1, self.label_img, "分形树调用函数", entry_width=int((self.width - 100) / 2 - 140)) + + if self.is_default != 0: + Button(self.cv, image=self.save_img if self.type == "add" else self.update_img, command=self.save, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, ).place(x=(self.width - 100) / 2, y=self.height - 60, width=100, height=self.label_height, anchor=NW) + + self.basic_label_image = ImageTk.PhotoImage(Image.open("./images/文字背景@3x.png").resize((int((self.width - 100) / 2), 30))) + + # 分形树绘制表单 + self.cv.create_image(35 + int((self.width - 100) / 2) + 30, 30 + (self.label_height + 15) * 2, image=self.basic_label_image, anchor=NW) + self.cv.create_text(35 + int((self.width - 100) / 2) + 30 + int((self.width - 100) / 4), 30 + (self.label_height + 15) * 2 + 15, text="分形图案绘制函数", font=("黑体", 14)) + self.function_code = Text(self.cv, font=("Arial", 14), bg="#bce7f7", highlightthickness=0, highlightcolor="#bce7f7", + spacing1=5, spacing2=3, spacing3=3, wrap="none") + self.function_code.place(x=35 + int((self.width - 100) / 2) + 30, y=30 + (self.label_height + 15) * 2 + 30, + height=self.height - 250, width=int((self.width - 100) / 2)) + + # 基本图形绘制表单 + self.cv.create_image(35, 30 + (self.label_height + 15) * 2, image=self.basic_label_image, anchor=NW) + self.cv.create_text(35 + int((self.width - 100) / 4), 30 + (self.label_height + 15) * 2 + 15, text="基本图案绘制函数", font=("黑体", 14)) + self.basic_pattern = Text(self.cv, font=("Arial", 14), bg="#bce7f7", highlightthickness=0, + spacing1=5, spacing2=3, spacing3=3, wrap="none", undo=True) + self.basic_pattern.place(x=35, y=30 + (self.label_height + 15) * 2 + 30, width=int((self.width - 100) / 2), height=285) + + # 初始变量表单 + self.cv.create_image(35, 30 + (self.label_height + 15) * 2 + 30 + 285 + 15, image=self.basic_label_image, anchor=NW) + self.cv.create_text(35 + int((self.width - 100) / 4), 30 + (self.label_height + 15) * 2 + 30 + 285 + 30, text="初始变量", + font=("黑体", 14)) + self.var_tree = Text(self.cv, font=("Arial", 14), bg="#bce7f7", highlightthickness=0, highlightcolor="#bce7f7", + spacing1=10, spacing2=5, spacing3=5, wrap="none") + self.var_tree.place(x=35, y=30 + (self.label_height + 15) * 2 + 30 + 280 + 45, + height=290, width=int((self.width - 100) / 2)) + + +class SelectFractalFrame(Frame): + # todo: 右上方分形图案单选框类 + def __init__(self, master, *args, ** kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.img = ImageTk.PhotoImage(Image.open("./images/上部背景@3x.png").resize( + (int(self.width), self.height))) + Label(self, width=self.width, height=self.height, image=self.img).place(x=0, y=0, anchor=NW) + Label(self, text="分形图案类型", font=("黑体", 14, "bold"), bg="#f7f7f7", ).place(x=10, y=10) + self.button_img = ImageTk.PhotoImage(Image.open("./images/新增分形图案类型@3x.png").resize((120, 36))) + Button(self, image=self.button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.add_fractal_tree).place(x=280, y=8) + self.update_button_img = ImageTk.PhotoImage(Image.open("./images/修改分形图案@3x.png").resize((120, 36))) + Button(self, image=self.update_button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.update_fractal_tree).place(x=150, y=8) + self.select_frame = Frame(self, width=self.width, height=self.height * 0.8, bg="#f7f7f7") + self.select_frame.place(x=0, y=self.height * 0.2) + self.create_select_menu() + + def add_fractal_tree(self): + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + x, y = int(screen_width - screen_width * 0.65) // 2, int(screen_height - screen_height * 0.8) // 2 + top_window = AddFractal(self, "add", width=screen_width * 0.65, height=screen_height * 0.8) + top_window.geometry(f'{int(screen_width * 0.65)}x{int(screen_height * 0.8)}+{x}+{y}') + top_window.mainloop() + + def update_fractal_tree(self): + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + x, y = int(screen_width - screen_width * 0.65) // 2, int(screen_height - screen_height * 0.8) // 2 + top_window = AddFractal(self, "update", width=screen_width * 0.65, height=screen_height * 0.8, fractal_id=self.master.chose_fractal.get()) + top_window.geometry(f'{int(screen_width * 0.65)}x{int(screen_height * 0.8)}+{x}+{y}') + top_window.mainloop() + + def create_select_menu(self): + # todo: 创建分形图案单选框 + data_frame = self.db.execute("select * from fractal") + yscro = Scrollbar(self.select_frame, orient=VERTICAL) + yscro.place(x=self.width - 20, y=0, height=self.height * 0.8, width=20, anchor='nw') + canvas = Canvas(self.select_frame, width=self.width - 20, height=self.height * 0.8, bg="#f7f7f7") + canvas.place(x=0, y=0, anchor='nw') + f2 = Frame(canvas, bg="#f7f7f7", width=self.width * 0.8, height=self.height * 0.8) + canvas.create_window((0, 0), window=f2, anchor=NW) + self.master.chose_fractal = IntVar() + self.master.chose_fractal.set(data_frame.loc[0:]["id"].tolist()[0]) + for data in data_frame.itertuples(index=False): + f_id, name, e_name, basic_pattern, function_code = data[0], data[1], data[2], data[3], data[4] + Radiobutton(f2, text=f"{name} {e_name}", value=f_id, command=lambda message=f"{name} {e_name}": self.master.update_select(message), + variable=self.master.chose_fractal, font=("", 18), bg="#f7f7f7").pack(ipadx=10, anchor="w") + canvas.update() + canvas.config(scrollregion=canvas.bbox("all"), yscrollcommand=yscro.set) # 设置画布的滚动区域 + yscro.config(command=canvas.yview) + + +class FormFractalFrame(Frame): + # todo: 右下方变量填写类 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.var_dict = {} + self.img = ImageTk.PhotoImage(Image.open("./images/上部背景@3x.png").resize( + (int(self.width), self.height))) + Label(self, width=self.width, height=self.height, image=self.img).place(x=0, y=0, anchor=NW) + Label(self, text="分形参数设置", font=("黑体", 14, "bold"), bg="#f7f7f7", ).place(x=10, y=10) + self.create_form() + self.button_img = ImageTk.PhotoImage(Image.open("./images/基本图案绘制@3x.png").resize((90, 36))) + Button(self, image=self.button_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.master.basic_tree_canvas.draw_basic_tree).place(x=10, y=self.height - 50) + self.button2_img = ImageTk.PhotoImage(Image.open("./images/绘制参数更新@3x.png").resize((90, 36))) + Button(self, image=self.button2_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.update_fractal_var).place(x=100 + 5, y=self.height - 50) + self.button3_img = ImageTk.PhotoImage(Image.open("./images/绘制@3x.png").resize((70, 36))) + Button(self, image=self.button3_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=lambda params=self.var_dict: self.master.fractal_tree_canvas.draw_fractal_tree(params)).place(x=100 * 2 + 5, y=self.height - 50) + self.button4_img = ImageTk.PhotoImage(Image.open("./images/删除图案@3x.png").resize((90, 36))) + Button(self, image=self.button4_img, bd=0, relief="solid", bg="#f7f7f7", + highlightthickness=0, command=self.delete_fractal).place(x=95 * 3, y=self.height - 50) + + def delete_fractal(self): + """ + 删除分形树 + :return: + """ + result = messagebox.askquestion("确认框", "您确定要执行此操作吗?") + if not result == "yes": return - # 左枝点 - end_point1 = (start_point[0] - length * math.sin(math.radians(angle)), - start_point[1] - length * math.cos(math.radians(angle))) - # 右枝点 - end_point2 = (start_point[0] + length * math.sin(math.radians(angle)), - start_point[1] - length * math.cos(math.radians(angle))) - # 画三角形 - canvas.create_polygon(start_point, end_point1, end_point2, fill='LightBlue4', outline='white') - # 画左枝 - Triangle_tree(depth - 1, percent, end_point1, angle, length * percent, canvas) - # 画右枝 - Triangle_tree(depth - 1, percent, end_point2, angle, length * percent, canvas) - # canvas.update() - # canvas.after(10) - - # 清除画布 - cv_big.delete("all") - # 将初始参数传入函数 - Triangle_tree(FinishLevel_tri, TreePercent_tri, InitPoint_tri, InitAngle_tri, InitLong_tri, cv_big) - # 在底部的结果输出框输出分形树的绘制参数 - output_text.delete("1.0", "end") - text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, treePercent={}, initPoint={}, initAngle={}, " \ - "initLong={}".format(FinishLevel_tri, TreePercent_tri, InitPoint_tri, - InitAngle_tri, InitLong_tri) - output_text.insert(tk.INSERT, text) - - -# 方形分形 Rect_Fractal -# 参数初始化 -FinishLevel_Rect = 10 -LeftPoint_Rect = (350, 410) -RightPoint_Rect = (450, 410) -InitAngle_Rect = 45 -params_Rect = " 分形层数:finishLevel={}\n" \ - " 左下点:leftPoint={}\n" \ - " 右下点:rightPoint={}\n" \ - " 初始角:initAngle={}".format(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect) - - -# 方形参数更新函数 -def update_params_Rect(): - new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 - new_params = new_str.split('\n') - new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 - # 参数更新 - global FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect - FinishLevel_Rect = int(new_params[0]) - LeftPoint_Rect = tuple(map(int, new_params[1][1:-1].split(','))) - RightPoint_Rect = tuple(map(int, new_params[2][1:-1].split(','))) - InitAngle_Rect = int(new_params[3]) - - -# 方形基本图案函数 -def Rect_Pattern(): - cv_small.delete("all") # 清空画布 - cv_small.create_rectangle(35, 10, 155, 120, outline='red', fill='white', width=2) - - -# 方形分形树执行函数 -def run_Rect_tree(): - # 方形分形树函数 - def Rect_tree(depth, point1, point2, angle, canvas): - # 直线的旋转,point1是定点 - def rotate(point1, point2, angle): - x1, y1 = point1[0], point1[1] - x2, y2 = point2[0], point2[1] - x = x1 + (x2 - x1) * math.cos(math.radians(angle)) + (y2 - y1) * math.sin(math.radians(angle)) - y = y1 + (y2 - y1) * math.cos(math.radians(angle)) - (x2 - x1) * math.sin(math.radians(angle)) - point = (x, y) - # print(point) - return point - - # 直线的缩放,point1是定点 - def zoom(point1, point2, ratio): - x1, y1 = point1[0], point1[1] - x2, y2 = point2[0], point2[1] - x = x1 + (x2 - x1) * ratio - y = y1 + (y2 - y1) * ratio - point = (x, y) - return point - - point3 = rotate(point1, point2, 90) - point4 = rotate(point2, point1, 270) - # print(point1,point2,point3,point4) - # 画正方形 - canvas.create_polygon(point1, point2, point4, point3, fill='LightBlue4', outline='white') - if depth == 0: - return - point = rotate(point3, point4, angle) # 旋转 - point = zoom(point3, point, math.cos(math.radians(angle))) # 缩放 - Rect_tree(depth - 1, point, point4, angle, canvas) # 画左枝 - Rect_tree(depth - 1, point3, point, angle, canvas) # 画右枝 - - # 清除画布 - cv_big.delete("all") - # 将初始参数传入函数 - Rect_tree(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect, cv_big) - # 在底部的结果输出框输出分形树的绘制参数 - output_text.delete("1.0", "end") - text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, leftPoint={}, rightPoint={}, initAngle={}" \ - .format(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect) - output_text.insert(tk.INSERT, text) - - -# 按钮【删除选项】的回调函数 -def delete_rb(): - fractal_type = shape_var.get() # 获取用户选择的分形类型 - # 遍历 Frame组件中的所有单选框 - for radio_button in frame.pack_slaves(): - # 如果选中对象是单选框且与单选框的值与 fractal_type相等,删除单选框 - if isinstance(radio_button, tk.Radiobutton) and radio_button["value"] == fractal_type: - radio_button.destroy() - - -# 连接到数据库 -def mysql_chart(table_query): - import mysql.connector - - # 连接到MySQL数据库 - cnx = mysql.connector.connect( - host='localhost', - user='root', - password='123456', - db='ec' - ) - - # 创建游标对象 - cursor = cnx.cursor() - - # 执行SQL语句来创建数据表 - cursor.execute(table_query) - - # 提交事务并关闭连接 - cnx.commit() - cursor.close() - cnx.close() - - -# 建立数据库连接 -def connect_To_database(): - try: - conn = pymysql.connect( - host='localhost', - user='root', - password='123456', - db='ec', - charset='utf8' - ) - # print('连接成功') - return conn - except pymysql.Error as e: - print('连接失败!', e) - - -# 文本框内的参数随着单选框的变化实时更新 -def update_Text(): - params_text.delete(1.0, tk.END) # 清空文本框中的内容 - fractal_type = shape_var.get() # 获取用户选择的分形类型 - # print(fractal_type) - # 根据分形类型在文本框内显示不同的分形参数字符串 - if fractal_type == 'Y': - params_text.insert(tk.INSERT, params_Y) - elif fractal_type == 'Triangle': - params_text.insert(tk.INSERT, params_Triangle) - elif fractal_type == 'Rect': - params_text.insert(tk.INSERT, params_Rect) - # 如果分形类型在分形参数输出字典中,运行相应的代码 - # elif fractal_type in str_params_dict: - # code = str_params_dict[fractal_type] - # exec(code) - conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') - df = pd.read_sql('select * from fractal', con=conn) - for i in df['fractal_e']: - # print(i) - if fractal_type == i: - code = df[df['fractal_e'] == i].params_initial.values[0] - exec(code) - code1 = df[df['fractal_e'] == i].str_params.values[0] - exec(code1) - conn.close() - - -def Y_pattern(): - cv_small.delete("all") # 清除画布 - cv_small.create_line(50, 30, 110, 90, fill='red', width=2) # 左臂 - cv_small.create_line(170, 30, 110, 90, fill='red', width=2) # 右臂 - cv_small.create_line(110, 160, 110, 90, fill='red', width=2) # 中心线 - - -# 按钮【基本图案绘制】的回调函数 -def draw_pattern(): - fractal_type = shape_var.get() # 获取用户选择的分形类型 - # 根据分形类型 绘制基本图案 - if fractal_type == 'Y': - Y_pattern() - elif fractal_type == 'Triangle': - Triangle_Pattern() - elif fractal_type == 'Rect': - Rect_Pattern() - - # 如果分形类型在基本图案绘制函数字典中,执行相应的代码 - # elif fractal_type in pattern_dict: - # code = pattern_dict[fractal_type] - # exec(code) - conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') - df = pd.read_sql('select * from fractal', con=conn) - for i in df['fractal_e']: - if fractal_type == i: - code = df[df['fractal_e'] == i].pattern.values[0] - exec(code) - conn.close() - - -# 按钮【绘制】的回调函数 -def draw_tree(): - fractal_type = shape_var.get() # 获取用户选择的分形类型 - # 根据分形类型 绘制分形树 - if fractal_type == 'Y': - run_Y_tree() - elif fractal_type == 'Triangle': - run_Triangle_tree() - elif fractal_type == 'Rect': - run_Rect_tree() - - # 如果分形类型在分形树绘制函数字典中,执行相应的代码 - # elif fractal_type in tree_dict: - # code = tree_dict[fractal_type] - # exec(code) - conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') - df = pd.read_sql('select * from fractal', con=conn) - for i in df['fractal_e']: - if fractal_type == i: - code = df[df['fractal_e'] == i].tree.values[0] - exec(code) - conn.close() - - -# 按钮【绘制参数设置】的回调函数 -def update_params(): - fractal_type = shape_var.get() # 获取用户选择的分形类型 - # 根据分形类型 执行对应的参数更新函数 - if fractal_type == 'Y': - update_params_Y() - elif fractal_type == 'Triangle': - update_params_Triangle() - elif fractal_type == 'Rect': - update_params_Rect() - - # 如果分形类型在参数更新字典中,运行相应的代码 - # if fractal_type in update_params_dict: - # code = update_params_dict[fractal_type] - # exec(code) - conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') - df = pd.read_sql('select * from fractal', con=conn) - for i in df['fractal_e']: - if fractal_type == i: - code = df[df['fractal_e'] == i].updata_tree.values[0] - exec(code) - conn.close() - - -# 按钮【新增分形图案类型】的回调函数 -def add_fractal(): - # 按钮【添加】的回调函数,将分形图案对应的函数模块增加到相关字典 - def add_function(): - # 获取分形名称,更改单选框名字 - name_fractal = text_name.get('1.0', 'end-1c') # 文本框控件中第一个字符的位置是 1.0,'end-1c'返回的输入中不包含换行符 - # print(name_fractal) - # 获取分形单选框的值 - fractal_type = text_radio.get('1.0', 'end-1c') - # print(fractal_type) - # 创建单选框 - rb = tk.Radiobutton(frame, text=name_fractal, variable=shape_var, value=fractal_type, bg="white", font=ft1) - rb.pack(anchor='w') - - # 执行参数初始化的代码 - params_code = text_param.get('1.0', 'end-1c') - # exec(params_code) - global str_params_dict, pattern_dict, tree_dict, update_params_dict - # 分形参数输出字典 - str_code = text_str.get('1.0', 'end-1c') - str_params_dict[fractal_type] = str_code - # 基本图案绘制函数字典 - pattern_code = text_pattern.get('1.0', 'end-1c') - # pattern_dict[fractal_type] = pattern_code - # 分形树绘制函数字典 - tree_code = text_tree.get('1.0', 'end-1c') - # tree_dict[fractal_type] = tree_code - # 参数更新字典 - update_code = text_up.get('1.0', 'end-1c') - # update_params_dict[fractal_type] = update_code - - # 添加后关闭窗口 - small_root2.destroy() - - list1 = [(name_fractal, fractal_type, params_code, str_code, pattern_code, tree_code, update_code)] - conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') - insert_query = "insert into fractal (name,fractal_e,params_initial,str_params,pattern,tree,updata_tree) " \ - "values (%s,%s,%s,%s,%s,%s,%s)" - - tree.insert_data(conn, insert_query, list1[0]) - - # 弹出一个添加分形代码的窗口 - small_root2 = tk.Tk() - small_root2.geometry("1000x700+200+50") - small_root2.title("新增分形图案类型") - # 分形名称,读取为单选框的名字 - lab_name = tk.Label(small_root2, text="分形名称:", font=ft1) - lab_name.place(x=40, y=10, width=100, height=30, anchor='nw') - text_name = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_name.configure(font=ft3) - text_name.place(x=140, y=10, width=340, height=30) - # 分形单选框的值,读取为单选框的值 - lab_radio = tk.Label(small_root2, text="分形英文简写:", font=ft1) - lab_radio.place(x=520, y=10, width=140, height=30, anchor='nw') - text_radio = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_radio.configure(font=ft3) - text_radio.place(x=660, y=10, width=300, height=30) - # 分形参数初始化,读取的代码可以直接运行 - lab_param = tk.Label(small_root2, text="请输入分形参数初始化的代码:", font=ft1) - lab_param.place(x=40, y=50, width=280, height=30, anchor='nw') - text_param = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_param.configure(font=ft3, spacing1=5) - text_param.place(x=40, y=85, width=440, height=140) - # 分形参数字符串形式输出,后续读取代码到分形参数输出字典str_params_dict - lab_str = tk.Label(small_root2, text="请输入分形参数字符串形式输出的代码:", font=ft1) - lab_str.place(x=40, y=230, width=360, height=30, anchor='nw') - text_str = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_str.configure(font=ft3, spacing1=5) - text_str.place(x=40, y=265, width=440, height=140) - # print(text_str) - # 参数更新,后续读取代码到参数更新字典update_params_dict - lab_up = tk.Label(small_root2, text="请输入分形参数更新的代码:", font=ft1) - lab_up.place(x=40, y=410, width=260, height=30, anchor='nw') - text_up = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_up.configure(font=ft3, spacing1=5) - text_up.place(x=40, y=445, width=440, height=145) - # 输入基本图案函数,后续读取代码到基本图案绘制函数字典pattern_dict - lab_pattern = tk.Label(small_root2, text="请输入基本图案绘制函数:", font=ft1) - lab_pattern.place(x=520, y=50, width=240, height=30, anchor='nw') - text_pattern = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_pattern.configure(font=ft3, spacing1=5) - text_pattern.place(x=520, y=85, width=440, height=240) - # 输入分形树函数,后续读取代码到分形树绘制函数字典tree_dict - lab_tree = tk.Label(small_root2, text="请输入分形树绘制函数:", font=ft1) - lab_tree.place(x=520, y=330, width=220, height=30, anchor='nw') - text_tree = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") - text_tree.configure(font=ft3, spacing1=5) - text_tree.place(x=520, y=365, width=440, height=230) - # 按钮【添加】 - button_add = tk.Button(small_root2, text="添加", command=add_function, font=ft2) - button_add.place(x=450, y=610, width=100, height=35, anchor='nw') - - -def main(): + fractal_id = self.master.chose_fractal.get() + DbUtil.delete_fractal(fractal_id) + self.master.flush() + self.master.message.show_message("删除成功!") + + def update_fractal_var(self): + # todo: 绘制参数更新 + text = self.var_text.get(0.0, "end").strip() + try: + for i in text.split("\n"): + i = i.replace(" ", "") + var = i.split(":")[1].split("=") + self.var_dict[var[0]] = var[1] + except Exception as E: + messagebox.showerror("注意", message=str(f"{E}\n变量格式错误,格式如下:\n分形层数:finishLevel=10")) + + def create_form(self): + # todo: 分形图案变量生成 + data_frame = self.db.query_fractal_by_id(self.master.chose_fractal.get()).iloc[0] + self.var_text = Text(self, font=("Arial", 14), bg="#f7f7f7", highlightthickness=0, highlightcolor="#f7f7f7", + spacing1=10, spacing2=5, spacing3=5, wrap="none") + self.var_text.place(x=0, y=self.height * 0.2, width=self.width, height=self.height * 0.6) + self.var_text.insert(0.0, data_frame["vars"]) + text = self.var_text.get(0.0, "end").strip() + try: + for i in text.split("\n"): + self.master.message.show_message("\t" + i) + i = i.replace(" ", "") + var = i.split(":")[1].split("=") + self.var_dict[var[0]] = var[1] + except Exception as E: + messagebox.showerror("注意", message=str(f"{E}\n变量格式错误,格式如下:\n分形层数:finishLevel=10")) + + +class BasicTree(Canvas): + # 基本图案绘制画布类 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.background_img = ImageTk.PhotoImage(Image.open("./images/全览图@3x.png").resize((self.width + 20, self.height + 20))) + self.create_image(-5, -5, image=self.background_img, anchor=NW) + + def draw_basic_tree(self): + # todo: 绘制基本图案 + self.delete("all") + data_frame = self.db.query_fractal_by_id(self.master.chose_fractal.get()) + params = { + "canvas": self + } + try: + exec(data_frame["basic_pattern"].tolist()[0], params) + self.master.message.show_message(f"基本图案绘制成功!") + except Exception as E: + self.master.message.show_message(f"{E}", color="red") + + +class FractalTreeCanvas(Canvas): + # todo: 绘制分形树画布 + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + + def draw_fractal_tree(self, params): + try: + self.delete("all") + data_frame = self.db.query_fractal_by_id(self.master.chose_fractal.get()) + params = {key: eval(value) for key, value in params.items()} + params["canvas"] = self + params["math"] = math + params["sleep"] = sleep + exec(data_frame["function_code"].tolist()[0], params) + self.master.message.show_message("分形树绘制成功!") + except Exception as E: + self.master.message.show_message(f"{E}", "red") + + +class FractalTree(Canvas): + def __init__(self, master, *args, **kwargs): + super().__init__(master, *args, **kwargs) + self.db = DbUtil() + self.width = int(self.cget("width")) + self.height = int(self.cget("height")) + self.background_image = ImageTk.PhotoImage(Image.open("./images/大背景@3x.jpg").resize((self.width, self.height))) + self.create_image(0, 0, image=self.background_image, anchor=NW) + self.chose_fractal = 1 + self.function_code = "" + self.fractal_var = {} + self.init_window() + + def update_select(self, message): + # todo: 切换分形图案 + self.message.show_message(f"选择了{message},初始参数如下:") + self.form_fractal_frame.create_form() + + def flush(self): + self.select_fractal_frame.create_select_menu() + self.form_fractal_frame.create_form() + + def init_window(self): + """ + 初始化窗口,创建窗口并布局 + :return: + """ + # 创建下方消息显示框 + message_frame = Frame(self, width=self.width - 60, height=self.height * 0.2) + message_frame.place(x=15, y=self.height * 0.8 + 15, anchor=NW) + self.message = Message(message_frame, width=self.width - 60, height=self.height * 0.2 - 30) + self.message.pack(anchor=NW) + self.message.configure(bg="#85bbd1") + + # 分形树画布 + self.fractal_tree_canvas = FractalTreeCanvas(self, width=self.width * 0.73 - 10, height=self.height * 0.8 + 12, highlightthickness=0, bg="#b5e6f5") + self.fractal_tree_canvas.place(x=0, y=0, anchor=NW) + + # 基本图形绘制框 + self.basic_tree_canvas = BasicTree(self, width=150, height=150, bg="#e0eaf5", bd=0) + self.basic_tree_canvas.place(x=15, y=self.height * 0.8 - 150, anchor=NW) + + # 创建左上方分形图案选择框 + self.select_fractal_frame = SelectFractalFrame(self, width=self.width * 0.27 - 10, height=int((self.height * 0.8) / 2) - 10) + self.select_fractal_frame.place(x=self.width * 0.73, y=10, anchor=NW) + + # 创建左下方输入框 + self.form_fractal_frame = FormFractalFrame(self, width=self.width * 0.27 - 10, height=int((self.height * 0.8) / 2)) + self.form_fractal_frame.place(x=self.width * 0.73, y=self.height * 0.8 / 2 + 10, anchor=NW) + + +if __name__ == '__main__': # 创建主窗口 - root = tk.Tk() - w = root.winfo_screenwidth() - h = root.winfo_screenheight() - root.geometry("%dx%d" % (w, h)) - root.title("分形树 电脑的分辨率是%dx%d" % (root.winfo_screenwidth(), root.winfo_screenheight())) - root.geometry('1270x650') + root = Tk() root.title('分形树') - - # 创建新增分形图案类型所需的字典 - str_params_dict = {} - pattern_dict = {} - tree_dict = {} - update_params_dict = {} - - # 定义变量,用于存储用户选择的分形类型 - shape_var = tk.StringVar() - - # 设置字体 - ft1 = tf.Font(family="黑体", size=21) - ft2 = tf.Font(family="黑体", size=21, weight=tf.BOLD) - ft3 = tf.Font(family="黑体", size=18) - ft4 = tf.Font(family="黑体", size=19) - - # 创建一个标签 - lab1 = tk.Label(root, text="分形图案类型", font=ft1) - lab1.place(x=20, y=10, width=180, height=50, anchor='nw') - - # 创建一个按钮,用来新增分形图案类型 - button_addPattern = tk.Button(root, text="新增分形图案类型", command=add_fractal, font=ft2) - button_addPattern.place(x=500, y=10, width=270, height=50, anchor='ne') - - ## 滚动框的设置 - # 创建一个Canvas对象,使用该对象作为滚动区域 - canvas = tk.Canvas(root, width=445, height=160) - - # 创建一个列表框对象Rlist,并将其放入滚动区域中 - Rlist = tk.Listbox(canvas, width=445, height=20, bg='white', highlightthickness=1, highlightbackground="LightBlue") - - # 创建滚动条对象并与Canvas绑定,实现滚动条功能 - scrollbar = tk.Scrollbar(root, orient="vertical", command=canvas.yview) - canvas.configure(yscrollcommand=scrollbar.set) - - canvas.place(x=20, y=75, anchor='nw') - scrollbar.place(x=470, y=75, width=30, height=160, anchor='nw') - - # 创建一个Frame组件用于放置单选框 - frame = tk.Frame(Rlist, bg='white') - frame.place(anchor='nw') - - # 将列表框放入Canvas中,并设置Canvas窗口的大小 - box_id = canvas.create_window((0, 0), window=Rlist, anchor="nw") - Rlist.update_idletasks() # 更新视图 - canvas.config(scrollregion=canvas.bbox("all")) # 设置画布的滚动区域 - - # 添加单选框到 Frame组件 - rb_Y = tk.Radiobutton(frame, text="Y形分形 Y_Fractal", variable=shape_var, value='Y', bg="white", font=ft1) - rb_Y.pack(anchor='w') - rb_Triangle = tk.Radiobutton(frame, text="三角形分形 Triangle_Fractal", variable=shape_var, value='Triangle', - bg="white", font=ft1) - rb_Triangle.pack(anchor='w') - rb_Rect = tk.Radiobutton(frame, text="矩形分形 Rect_Fractal", variable=shape_var, value='Rect', bg="white", - font=ft1) - rb_Rect.pack(anchor='w') - - if os.path.exists('params.csv'): - df = pd.read_csv("params.csv") - for i in df["分型名称"]: - rb1 = tk.Radiobutton(frame, text=i, variable=shape_var, value=df[df['分型名称'] == i].分形英文.values[0], - bg="white", font=ft1) - rb1.pack(anchor='w') - - # 将默认选项设置为 Y 形分形 - rb_Y.select() - - # 创建一个标签 - lab2 = tk.Label(root, text="分形参数设置【参数含义:参量名=参量值】", font=ft4) - lab2.place(x=20, y=255, width=490, height=40, anchor='nw') - - # 大画布的宽度和高度变量,方便后期调整 - big_width = 880 - big_height = 690 - - # 创建蓝色边框的大画布 - cv_big = tk.Canvas(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - cv_big.config(width=big_width, height=big_height) - cv_big.place(x=530, y=10, anchor='nw') - - # 创建红色边框的小画布,宽高设置为大画布的1/4 - cv_small = tk.Canvas(cv_big, bg="white", highlightthickness=1, highlightbackground="tomato") - cv_small.config(width=big_width * 0.25, height=big_height * 0.25) - cv_small.place(x=0, y=big_height, anchor='sw') - - # 创建一个多行文本框 - params_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - params_text.configure(font=ft3, spacing1=15) - params_text.place(x=20, y=300, width=480, height=310, anchor='nw') - - # 初始化分形参数并输出 - params_str = params_Y - params_text.insert(tk.INSERT, params_str) - - # trace追踪变量w模式,回调函数update_text - shape_var.trace('w', lambda *args, str_params_dict=str_params_dict: update_Text()) - - # 创建四个按钮 - button_delete = tk.Button(root, text="删除\n选项", command=delete_rb, font=ft2) - button_delete.place(x=20, y=700, width=90, height=75, anchor='sw') - button_pattern = tk.Button(root, text="基本图\n案绘制", command=draw_pattern, font=ft2) - button_pattern.place(x=130, y=700, width=120, height=75, anchor='sw') - button_params = tk.Button(root, text="绘制参\n数设置", command=update_params, font=ft2) - button_params.place(x=270, y=700, width=120, height=75, anchor='sw') - button_drawTree = tk.Button(root, text="绘制", command=draw_tree, font=ft2) - button_drawTree.place(x=410, y=700, width=90, height=75, anchor='sw') - - # 创建底部输出框 - output_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - output_text.configure(font=ft3, spacing1=8) - text = " 结果输出:<分形绘制参数的字符串形式输出>" - output_text.insert(tk.INSERT, text) - output_text.place(x=20, y=800, width=1390, height=80, anchor='sw') - - # 进入消息循环 - root.mainloop() + screen_width = root.winfo_screenwidth() # winfo方法来获取当前电脑屏幕大小 + screen_height = root.winfo_screenheight() + root_attr = { + "width": screen_width * 0.8, + "height": screen_height * 0.8, + } + size = '%dx%d+%d+%d' % (root_attr['width'], root_attr['height'], (screen_width - root_attr['width']) / 2, + (screen_height - root_attr['height']) / 2 - 30) + root.geometry(size) + tree = FractalTree(root, width=root_attr["width"], height=root_attr["height"]) + tree.place(x=0, y=0, anchor=NW) + root.mainloop() -if __name__ == '__main__': - from pycallgraph2 import PyCallGraph - from pycallgraph2.output import GraphvizOutput - from pycallgraph2 import Config - from pycallgraph2 import GlobbingFilter - - output = GraphvizOutput(font_size=30) - output.output_file = "basic.png" - output.group_font_size = 40 - config = Config() - # config.trace_filter = GlobbingFilter(include=[ - # 'update_params_Triangle.*', - # 'yPattern.*', - # 'Rect_Pattern.*', - # 'run_Rect_tree.*', - # 'delete_rb.*', - # 'mysql_Text.*', - # 'Y_pattern.*', - # 'draw_pattern.*', - # 'draw_tree.*', - # 'update_params.*', - # 'add_fractal.*', - # 'main.*', - # ]) - with PyCallGraph(output=output, config=config): - # 创建主窗口 - root = tk.Tk() - w = root.winfo_screenwidth() - h = root.winfo_screenheight() - root.geometry("%dx%d" % (w, h)) - root.title("分形树 电脑的分辨率是%dx%d" % (root.winfo_screenwidth(), root.winfo_screenheight())) - root.geometry('1270x650') - root.title('分形树') - - # 创建新增分形图案类型所需的字典 - str_params_dict = {} - pattern_dict = {} - tree_dict = {} - update_params_dict = {} - - # 定义变量,用于存储用户选择的分形类型 - shape_var = tk.StringVar() - - # 设置字体 - ft1 = tf.Font(family="黑体", size=21) - ft2 = tf.Font(family="黑体", size=21, weight=tf.BOLD) - ft3 = tf.Font(family="黑体", size=18) - ft4 = tf.Font(family="黑体", size=19) - - # 创建一个标签 - lab1 = tk.Label(root, text="分形图案类型", font=ft1) - lab1.place(x=20, y=10, width=180, height=50, anchor='nw') - - # 创建一个按钮,用来新增分形图案类型 - button_addPattern = tk.Button(root, text="新增分形图案类型", command=add_fractal, font=ft2) - button_addPattern.place(x=500, y=10, width=270, height=50, anchor='ne') - - ## 滚动框的设置 - # 创建一个Canvas对象,使用该对象作为滚动区域 - canvas = tk.Canvas(root, width=445, height=160) - - # 创建一个列表框对象Rlist,并将其放入滚动区域中 - Rlist = tk.Listbox(canvas, width=445, height=20, bg='white', highlightthickness=1, highlightbackground="LightBlue") - - # 创建滚动条对象并与Canvas绑定,实现滚动条功能 - scrollbar = tk.Scrollbar(root, orient="vertical", command=canvas.yview) - canvas.configure(yscrollcommand=scrollbar.set) - - canvas.place(x=20, y=75, anchor='nw') - scrollbar.place(x=470, y=75, width=30, height=160, anchor='nw') - - # 创建一个Frame组件用于放置单选框 - frame = tk.Frame(Rlist, bg='white') - frame.place(anchor='nw') - - # 将列表框放入Canvas中,并设置Canvas窗口的大小 - box_id = canvas.create_window((0, 0), window=Rlist, anchor="nw") - Rlist.update_idletasks() # 更新视图 - canvas.config(scrollregion=canvas.bbox("all")) # 设置画布的滚动区域 - - # 添加单选框到 Frame组件 - rb_Y = tk.Radiobutton(frame, text="Y形分形 Y_Fractal", variable=shape_var, value='Y', bg="white", font=ft1) - rb_Y.pack(anchor='w') - rb_Triangle = tk.Radiobutton(frame, text="三角形分形 Triangle_Fractal", variable=shape_var, value='Triangle', - bg="white", font=ft1) - rb_Triangle.pack(anchor='w') - rb_Rect = tk.Radiobutton(frame, text="矩形分形 Rect_Fractal", variable=shape_var, value='Rect', bg="white", - font=ft1) - rb_Rect.pack(anchor='w') - - if os.path.exists('params.csv'): - df = pd.read_csv("params.csv") - for i in df["分型名称"]: - rb1 = tk.Radiobutton(frame, text=i, variable=shape_var, value=df[df['分型名称'] == i].分形英文.values[0], - bg="white", font=ft1) - rb1.pack(anchor='w') - - # 将默认选项设置为 Y 形分形 - rb_Y.select() - - # 创建一个标签 - lab2 = tk.Label(root, text="分形参数设置【参数含义:参量名=参量值】", font=ft4) - lab2.place(x=20, y=255, width=490, height=40, anchor='nw') - - # 大画布的宽度和高度变量,方便后期调整 - big_width = 880 - big_height = 690 - - # 创建蓝色边框的大画布 - cv_big = tk.Canvas(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - cv_big.config(width=big_width, height=big_height) - cv_big.place(x=530, y=10, anchor='nw') - - # 创建红色边框的小画布,宽高设置为大画布的1/4 - cv_small = tk.Canvas(cv_big, bg="white", highlightthickness=1, highlightbackground="tomato") - cv_small.config(width=big_width * 0.25, height=big_height * 0.25) - cv_small.place(x=0, y=big_height, anchor='sw') - - # 创建一个多行文本框 - params_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - params_text.configure(font=ft3, spacing1=15) - params_text.place(x=20, y=300, width=480, height=310, anchor='nw') - - # 初始化分形参数并输出 - params_str = params_Y - params_text.insert(tk.INSERT, params_str) - - # trace追踪变量w模式,回调函数update_text - shape_var.trace('w', lambda *args, str_params_dict=str_params_dict: update_Text()) - - # 创建四个按钮 - button_delete = tk.Button(root, text="删除\n选项", command=delete_rb, font=ft2) - button_delete.place(x=20, y=700, width=90, height=75, anchor='sw') - button_pattern = tk.Button(root, text="基本图\n案绘制", command=draw_pattern, font=ft2) - button_pattern.place(x=130, y=700, width=120, height=75, anchor='sw') - button_params = tk.Button(root, text="绘制参\n数设置", command=update_params, font=ft2) - button_params.place(x=270, y=700, width=120, height=75, anchor='sw') - button_drawTree = tk.Button(root, text="绘制", command=draw_tree, font=ft2) - button_drawTree.place(x=410, y=700, width=90, height=75, anchor='sw') - - # 创建底部输出框 - output_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") - output_text.configure(font=ft3, spacing1=8) - text = " 结果输出:<分形绘制参数的字符串形式输出>" - output_text.insert(tk.INSERT, text) - output_text.place(x=20, y=800, width=1390, height=80, anchor='sw') - - # 进入消息循环 - root.mainloop() diff --git a/fractaltree1.py b/fractaltree1.py new file mode 100644 index 0000000..b17623a --- /dev/null +++ b/fractaltree1.py @@ -0,0 +1,613 @@ +# -*- coding:utf-8 -*- + +import tkinter as tk +import tkinter.font as tf +import math +import pandas as pd +import pymysql +import os +from time import sleep + +# Y形分形 Y_Fractal +# 参数初始化 +FinishLevel_Y = 14 +TreePercent_Y = 0.7 +LeftAngle_Y = 30 +RightAngle_Y = 30 +InitPoint_Y = (420, 500) +InitAngle_Y = 90 +InitLong_Y = 150 + +# Y形分形参数的字符串形式输出 +params_Y = " 分形层数:finishLevel={}\n" \ + " 缩放比例:treePercent={}\n" \ + " 左枝倾角:leftAngle={}\n" \ + " 右枝倾角:rightAngle={}\n" \ + " 初始点:initPoint={}\n" \ + " 初始角:initAngle={}\n" \ + " 初始长度:initLong={}".format(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, + InitPoint_Y, InitAngle_Y, InitLong_Y) + + +# Y形基本图案函数 +def yPattern(): + cv_small.delete("all") # 清除画布 + cv_small.create_line(30, 10, 90, 70, fill='red', width=2) # 左臂 + cv_small.create_line(150, 10, 90, 70, fill='red', width=2) # 右臂 + cv_small.create_line(90, 140, 90, 70, fill='red', width=2) # 中心线 + + +# Y形树执行函数 +def run_Y_tree(): + # Y形分形树函数 + def Y_tree(depth, percent, left_angle, right_angle, start_point, angle, length, canvas): + if depth == 0: + return + end_point = (start_point[0] + length * math.cos(math.radians(angle)), + start_point[1] - length * math.sin(math.radians(angle))) + canvas.create_line(start_point, end_point, fill='LightBlue4', width=2) + Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle + right_angle, length * percent, + canvas) # 画右枝 + Y_tree(depth - 1, percent, left_angle, right_angle, end_point, angle - left_angle, length * percent, + canvas) # 画左枝 + canvas.update() + sleep(0.001) + + + # 清除画布 + cv_big.delete("all") + # 将初始参数传入函数 + Y_tree(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, InitAngle_Y, InitLong_Y, cv_big) + output_text.delete("1.0", "end") + # 在底部的结果输出框输出分形树的绘制参数 + text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, treePercent={}," \ + " leftAngle={}, rightAngle={}, initPoint={}, initAngle={}, initLong={}" \ + .format(FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, + InitAngle_Y, InitLong_Y) + output_text.insert(tk.INSERT, text) + + +# Y形分形参数更新函数 +def update_params_Y(): + new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 + new_params = new_str.split('\n') + new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 + # 参数更新 + global FinishLevel_Y, TreePercent_Y, LeftAngle_Y, RightAngle_Y, InitPoint_Y, InitAngle_Y, InitLong_Y + FinishLevel_Y = int(new_params[0]) + TreePercent_Y = float(new_params[1]) + LeftAngle_Y = int(new_params[2]) + RightAngle_Y = int(new_params[3]) + InitPoint_Y = tuple(map(int, new_params[4][1:-1].split(','))) + InitAngle_Y = int(new_params[5]) + InitLong_Y = int(new_params[6]) + + +# 三角形分形 Triangle_Fractal +# 参数初始化 +FinishLevel_tri = 14 +TreePercent_tri = 0.7 +InitPoint_tri = (420, 500) +InitAngle_tri = 30 +InitLong_tri = 170 +params_Triangle = " 分形层数:finishLevel={}\n" \ + " 缩放比例:treePercent={}\n" \ + " 初始点:initPoint={}\n" \ + " 初始角:initAngle={}\n" \ + " 初始长度:initLong={}".format(FinishLevel_tri, TreePercent_tri, InitPoint_tri, + InitAngle_tri, InitLong_tri) + + +# 三角形分形参数设置 +def update_params_Triangle(): + new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 + new_params = new_str.split('\n') + new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 + # 参数更新 + global FinishLevel_tri, TreePercent_tri, InitPoint_tri, InitAngle_tri, InitLong_tri + FinishLevel_tri = int(new_params[0]) + TreePercent_tri = float(new_params[1]) + InitPoint_tri = tuple(map(int, new_params[2][1:-1].split(','))) + InitAngle_tri = int(new_params[3]) + InitLong_tri = int(new_params[4]) + + +# 三角形基本图案函数 +def Triangle_Pattern(): + cv_small.delete("all") # 清除画布 + cv_small.create_polygon(80, 130, 20, 10, 140, 10, outline='red', fill='white', width=2) + + +# 三角形分形树执行函数(倒的坐标系) +def run_Triangle_tree(): + # 三角形分形树函数 + def Triangle_tree(depth, percent, start_point, angle, length, canvas): + if depth == 0: + return + # 左枝点 + end_point1 = (start_point[0] - length * math.sin(math.radians(angle)), + start_point[1] - length * math.cos(math.radians(angle))) + # 右枝点 + end_point2 = (start_point[0] + length * math.sin(math.radians(angle)), + start_point[1] - length * math.cos(math.radians(angle))) + # 画三角形 + canvas.create_polygon(start_point, end_point1, end_point2, fill='LightBlue4', outline='white') + # 画左枝 + Triangle_tree(depth - 1, percent, end_point1, angle, length * percent, canvas) + # 画右枝 + Triangle_tree(depth - 1, percent, end_point2, angle, length * percent, canvas) + # 清除画布 + cv_big.delete("all") + # 将初始参数传入函数 + Triangle_tree(FinishLevel_tri, TreePercent_tri, InitPoint_tri, InitAngle_tri, InitLong_tri, cv_big) + # 在底部的结果输出框输出分形树的绘制参数 + output_text.delete("1.0", "end") + text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, treePercent={}, initPoint={}, initAngle={}, " \ + "initLong={}".format(FinishLevel_tri, TreePercent_tri, InitPoint_tri, + InitAngle_tri, InitLong_tri) + output_text.insert(tk.INSERT, text) +# 方形分形 Rect_Fractal +# 参数初始化 +FinishLevel_Rect = 10 +LeftPoint_Rect = (350, 410) +RightPoint_Rect = (450, 410) +InitAngle_Rect = 45 +params_Rect = " 分形层数:finishLevel={}\n" \ + " 左下点:leftPoint={}\n" \ + " 右下点:rightPoint={}\n" \ + " 初始角:initAngle={}".format(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect) + + +# 方形参数更新函数 +def update_params_Rect(): + new_str = params_text.get("1.0", "end-1c") # 获取文本框中的分形参数字符串 + new_params = new_str.split('\n') + new_params = [x.split('=')[1].strip() for x in new_params] # 获取参数值 + # 参数更新 + global FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect + FinishLevel_Rect = int(new_params[0]) + LeftPoint_Rect = tuple(map(int, new_params[1][1:-1].split(','))) + RightPoint_Rect = tuple(map(int, new_params[2][1:-1].split(','))) + InitAngle_Rect = int(new_params[3]) + + +# 方形基本图案函数 +def Rect_Pattern(): + cv_small.delete("all") # 清空画布 + cv_small.create_rectangle(35, 10, 155, 120, outline='red', fill='white', width=2) + + +# 方形分形树执行函数 +def run_Rect_tree(): + # 方形分形树函数 + def Rect_tree(depth, point1, point2, angle, canvas): + # 直线的旋转,point1是定点 + def rotate(point1, point2, angle): + x1, y1 = point1[0], point1[1] + x2, y2 = point2[0], point2[1] + x = x1 + (x2 - x1) * math.cos(math.radians(angle)) + (y2 - y1) * math.sin(math.radians(angle)) + y = y1 + (y2 - y1) * math.cos(math.radians(angle)) - (x2 - x1) * math.sin(math.radians(angle)) + point = (x, y) + # print(point) + return point + # 直线的缩放,point1是定点 + def zoom(point1, point2, ratio): + x1, y1 = point1[0], point1[1] + x2, y2 = point2[0], point2[1] + x = x1 + (x2 - x1) * ratio + y = y1 + (y2 - y1) * ratio + point = (x, y) + return point + point3 = rotate(point1, point2, 90) + point4 = rotate(point2, point1, 270) + # print(point1,point2,point3,point4) + # 画正方形 + canvas.create_polygon(point1, point2, point4, point3, fill='LightBlue4', outline='white') + if depth == 0: + return + point = rotate(point3, point4, angle) # 旋转 + point = zoom(point3, point, math.cos(math.radians(angle))) # 缩放 + Rect_tree(depth - 1, point, point4, angle, canvas) # 画左枝 + Rect_tree(depth - 1, point3, point, angle, canvas) # 画右枝 + # 清除画布 + cv_big.delete("all") + # 将初始参数传入函数 + Rect_tree(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect, cv_big) + # 在底部的结果输出框输出分形树的绘制参数 + output_text.delete("1.0", "end") + text = " 结果输出:<分形绘制参数的字符串形式输出>\n finishLevel={}, leftPoint={}, rightPoint={}, initAngle={}" \ + .format(FinishLevel_Rect, LeftPoint_Rect, RightPoint_Rect, InitAngle_Rect) + output_text.insert(tk.INSERT, text) + + +# 按钮【删除选项】的回调函数 +def delete_rb(): + fractal_type = shape_var.get() # 获取用户选择的分形类型 + # 遍历 Frame组件中的所有单选框 + for radio_button in frame.pack_slaves(): + # 如果选中对象是单选框且与单选框的值与 fractal_type相等,删除单选框 + if isinstance(radio_button, tk.Radiobutton) and radio_button["value"] == fractal_type: + radio_button.destroy() + + + +# 文本框内的参数随着单选框的变化实时更新 +def update_Text(): + params_text.delete(1.0, tk.END) # 清空文本框中的内容 + fractal_type = shape_var.get() # 获取用户选择的分形类型 + if fractal_type == 'Y': + params_text.insert(tk.INSERT, params_Y) + elif fractal_type == 'Triangle': + params_text.insert(tk.INSERT, params_Triangle) + elif fractal_type == 'Rect': + params_text.insert(tk.INSERT, params_Rect) + conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') + df = pd.read_sql('select * from fractal', con=conn) + for i in df['fractal_e']: + # print(i) + if fractal_type == i: + code = df[df['fractal_e'] == i].params_initial.values[0] + exec(code) + code1 = df[df['fractal_e'] == i].str_params.values[0] + exec(code1) + conn.close() + + +def Y_pattern(): + canvas.delete("all") # 清除画布 + canvas.create_line(50, 30, 110, 90, fill='red', width=2) # 左臂 + canvas.create_line(170, 30, 110, 90, fill='red', width=2) # 右臂 + canvas.create_line(110, 160, 110, 90, fill='red', width=2) # 中心线 + + +# 按钮【基本图案绘制】的回调函数 +def draw_pattern(): + fractal_type = shape_var.get() # 获取用户选择的分形类型 + # 根据分形类型 绘制基本图案 + if fractal_type == 'Y': + Y_pattern() + elif fractal_type == 'Triangle': + Triangle_Pattern() + elif fractal_type == 'Rect': + Rect_Pattern() + conn = pymysql.connect(host='localhost', user='root', password='123123', database='ec') + df = pd.read_sql('select * from fractal', con=conn) + for i in df['fractal_e']: + if fractal_type == i: + code = df[df['fractal_e'] == i].pattern.values[0] + exec(code) + conn.close() + + +# 按钮【绘制】的回调函数 +def draw_tree(): + fractal_type = shape_var.get() # 获取用户选择的分形类型 + # 根据分形类型 绘制分形树 + if fractal_type == 'Y': + run_Y_tree() + elif fractal_type == 'Triangle': + run_Triangle_tree() + elif fractal_type == 'Rect': + run_Rect_tree() + conn = pymysql.connect(host='localhost', user='root', password='123123', database='ec') + df = pd.read_sql('select * from fractal', con=conn) + for i in df['fractal_e']: + if fractal_type == i: + code = df[df['fractal_e'] == i].tree.values[0] + exec(code) + conn.close() + + +# 按钮【绘制参数设置】的回调函数 +def update_params(): + fractal_type = shape_var.get() # 获取用户选择的分形类型 + # 根据分形类型 执行对应的参数更新函数 + if fractal_type == 'Y': + update_params_Y() + elif fractal_type == 'Triangle': + update_params_Triangle() + elif fractal_type == 'Rect': + update_params_Rect() + conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') + df = pd.read_sql('select * from fractal', con=conn) + for i in df['fractal_e']: + if fractal_type == i: + code = df[df['fractal_e'] == i].updata_tree.values[0] + exec(code) + conn.close() + + +# 按钮【新增分形图案类型】的回调函数 +def add_fractal(): + # 按钮【添加】的回调函数,将分形图案对应的函数模块增加到相关字典 + def add_function(): + # 获取分形名称,更改单选框名字 + name_fractal = text_name.get('1.0', 'end-1c') # 文本框控件中第一个字符的位置是 1.0,'end-1c'返回的输入中不包含换行符 + # print(name_fractal) + # 获取分形单选框的值 + fractal_type = text_radio.get('1.0', 'end-1c') + # print(fractal_type) + # 创建单选框 + rb = tk.Radiobutton(frame, text=name_fractal, variable=shape_var, value=fractal_type, bg="white", font=ft1) + rb.pack(anchor='w') + # 执行参数初始化的代码 + params_code = text_param.get('1.0', 'end-1c') + # exec(params_code) + global str_params_dict, pattern_dict, tree_dict, update_params_dict + # 分形参数输出字典 + str_code = text_str.get('1.0', 'end-1c') + str_params_dict[fractal_type] = str_code + # 基本图案绘制函数字典 + pattern_code = text_pattern.get('1.0', 'end-1c') + # pattern_dict[fractal_type] = pattern_code + # 分形树绘制函数字典 + tree_code = text_tree.get('1.0', 'end-1c') + # tree_dict[fractal_type] = tree_code + # 参数更新字典 + update_code = text_up.get('1.0', 'end-1c') + # update_params_dict[fractal_type] = update_code + # 添加后关闭窗口 + small_root2.destroy() + list1 = [(name_fractal, fractal_type, params_code, str_code, pattern_code, tree_code, update_code)] + conn = pymysql.connect(host='localhost', user='root', password='123456', database='ec') + insert_query = "insert into fractal (name,fractal_e,params_initial,str_params,pattern,tree,updata_tree) " \ + "values (%s,%s,%s,%s,%s,%s,%s)" + + tree.insert_data(conn, insert_query, list1[0]) + # 弹出一个添加分形代码的窗口 + small_root2 = tk.Tk() + small_root2.geometry("1000x700+200+50") + small_root2.title("新增分形图案类型") + # 分形名称,读取为单选框的名字 + lab_name = tk.Label(small_root2, text="分形名称:", font=ft1) + lab_name.place(x=40, y=10, width=100, height=30, anchor='nw') + text_name = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_name.configure(font=ft3) + text_name.place(x=140, y=10, width=340, height=30) + # 分形单选框的值,读取为单选框的值 + lab_radio = tk.Label(small_root2, text="分形英文简写:", font=ft1) + lab_radio.place(x=520, y=10, width=140, height=30, anchor='nw') + text_radio = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_radio.configure(font=ft3) + text_radio.place(x=660, y=10, width=300, height=30) + # 分形参数初始化,读取的代码可以直接运行 + lab_param = tk.Label(small_root2, text="请输入分形参数初始化的代码:", font=ft1) + lab_param.place(x=40, y=50, width=280, height=30, anchor='nw') + text_param = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_param.configure(font=ft3, spacing1=5) + text_param.place(x=40, y=85, width=440, height=140) + # 分形参数字符串形式输出,后续读取代码到分形参数输出字典str_params_dict + lab_str = tk.Label(small_root2, text="请输入分形参数字符串形式输出的代码:", font=ft1) + lab_str.place(x=40, y=230, width=360, height=30, anchor='nw') + text_str = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_str.configure(font=ft3, spacing1=5) + text_str.place(x=40, y=265, width=440, height=140) + # print(text_str) + # 参数更新,后续读取代码到参数更新字典update_params_dict + lab_up = tk.Label(small_root2, text="请输入分形参数更新的代码:", font=ft1) + lab_up.place(x=40, y=410, width=260, height=30, anchor='nw') + text_up = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_up.configure(font=ft3, spacing1=5) + text_up.place(x=40, y=445, width=440, height=145) + # 输入基本图案函数,后续读取代码到基本图案绘制函数字典pattern_dict + lab_pattern = tk.Label(small_root2, text="请输入基本图案绘制函数:", font=ft1) + lab_pattern.place(x=520, y=50, width=240, height=30, anchor='nw') + text_pattern = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_pattern.configure(font=ft3, spacing1=5) + text_pattern.place(x=520, y=85, width=440, height=240) + # 输入分形树函数,后续读取代码到分形树绘制函数字典tree_dict + lab_tree = tk.Label(small_root2, text="请输入分形树绘制函数:", font=ft1) + lab_tree.place(x=520, y=330, width=220, height=30, anchor='nw') + text_tree = tk.Text(small_root2, highlightthickness=1, highlightbackground="LightBlue") + text_tree.configure(font=ft3, spacing1=5) + text_tree.place(x=520, y=365, width=440, height=230) + # 按钮【添加】 + button_add = tk.Button(small_root2, text="添加", command=add_function, font=ft2) + button_add.place(x=450, y=610, width=100, height=35, anchor='nw') + + +def main(): + # 创建主窗口 + root = tk.Tk() + w = root.winfo_screenwidth() + h = root.winfo_screenheight() + root.geometry("%dx%d" % (w, h)) + root.title("分形树 电脑的分辨率是%dx%d" % (root.winfo_screenwidth(), root.winfo_screenheight())) + root.geometry('1270x650') + root.title('分形树') + # 创建新增分形图案类型所需的字典 + str_params_dict = {} + pattern_dict = {} + tree_dict = {} + update_params_dict = {} + # 定义变量,用于存储用户选择的分形类型 + shape_var = tk.StringVar() + # 设置字体 + ft1 = tf.Font(family="黑体", size=21) + ft2 = tf.Font(family="黑体", size=21, weight=tf.BOLD) + ft3 = tf.Font(family="黑体", size=18) + ft4 = tf.Font(family="黑体", size=19) + # 创建一个标签 + lab1 = tk.Label(root, text="分形图案类型", font=ft1) + lab1.place(x=20, y=10, width=180, height=50, anchor='nw') + # 创建一个按钮,用来新增分形图案类型 + button_addPattern = tk.Button(root, text="新增分形图案类型", command=add_fractal, font=ft2) + button_addPattern.place(x=500, y=10, width=270, height=50, anchor='ne') + ## 滚动框的设置 + # 创建一个Canvas对象,使用该对象作为滚动区域 + canvas = tk.Canvas(root, width=445, height=160) + # 创建一个列表框对象Rlist,并将其放入滚动区域中 + Rlist = tk.Listbox(canvas, width=445, height=20, bg='white', highlightthickness=1, highlightbackground="LightBlue") + # 创建滚动条对象并与Canvas绑定,实现滚动条功能 + scrollbar = tk.Scrollbar(root, orient="vertical", command=Rlist.yview) + canvas.configure(yscrollcommand=scrollbar.set) + canvas.place(x=20, y=75, anchor='nw') + scrollbar.place(x=470, y=75, width=30, height=160, anchor='nw') + # 创建一个Frame组件用于放置单选框 + frame = tk.Frame(Rlist, bg='white') + frame.place(anchor='nw') + # 将列表框放入Canvas中,并设置Canvas窗口的大小 + box_id = canvas.create_window((0, 0), window=Rlist, anchor="nw") + Rlist.update_idletasks() # 更新视图 + canvas.config(scrollregion=canvas.bbox("all")) # 设置画布的滚动区域 + # 添加单选框到 Frame组件 + rb_Y = tk.Radiobutton(frame, text="Y形分形 Y_Fractal", variable=shape_var, value='Y', bg="white", font=ft1) + rb_Y.pack(anchor='w') + rb_Triangle = tk.Radiobutton(frame, text="三角形分形 Triangle_Fractal", variable=shape_var, value='Triangle', + bg="white", font=ft1) + rb_Triangle.pack(anchor='w') + rb_Rect = tk.Radiobutton(frame, text="矩形分形 Rect_Fractal", variable=shape_var, value='Rect', bg="white", + font=ft1) + rb_Rect.pack(anchor='w') + if os.path.exists('params.csv'): + df = pd.read_csv("params.csv") + for i in df["分型名称"]: + rb1 = tk.Radiobutton(frame, text=i, variable=shape_var, value=df[df['分型名称'] == i].分形英文.values[0], + bg="white", font=ft1) + rb1.pack(anchor='w') + # 将默认选项设置为 Y 形分形 + rb_Y.select() + # 创建一个标签 + lab2 = tk.Label(root, text="分形参数设置【参数含义:参量名=参量值】", font=ft4) + lab2.place(x=20, y=255, width=490, height=40, anchor='nw') + # 大画布的宽度和高度变量,方便后期调整 + big_width = 880 + big_height = 690 + # 创建蓝色边框的大画布 + cv_big = tk.Canvas(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + cv_big.config(width=big_width, height=big_height) + cv_big.place(x=530, y=10, anchor='nw') + # 创建红色边框的小画布,宽高设置为大画布的1/4 + cv_small = tk.Canvas(cv_big, bg="white", highlightthickness=1, highlightbackground="tomato") + cv_small.config(width=big_width * 0.25, height=big_height * 0.25) + cv_small.place(x=0, y=big_height, anchor='sw') + # 创建一个多行文本框 + params_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + params_text.configure(font=ft3, spacing1=15) + params_text.place(x=20, y=300, width=480, height=310, anchor='nw') + # 初始化分形参数并输出 + params_str = params_Y + params_text.insert(tk.INSERT, params_str) + # trace追踪变量w模式,回调函数update_text + shape_var.trace('w', lambda *args, str_params_dict=str_params_dict: update_Text()) + # 创建四个按钮 + button_delete = tk.Button(root, text="删除\n选项", command=delete_rb, font=ft2) + button_delete.place(x=20, y=700, width=90, height=75, anchor='sw') + button_pattern = tk.Button(root, text="基本图\n案绘制", command=draw_pattern, font=ft2) + button_pattern.place(x=130, y=700, width=120, height=75, anchor='sw') + button_params = tk.Button(root, text="绘制参\n数设置", command=update_params, font=ft2) + button_params.place(x=270, y=700, width=120, height=75, anchor='sw') + button_drawTree = tk.Button(root, text="绘制", command=draw_tree, font=ft2) + button_drawTree.place(x=410, y=700, width=90, height=75, anchor='sw') + # 创建底部输出框 + output_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + output_text.configure(font=ft3, spacing1=8) + text = " 结果输出:<分形绘制参数的字符串形式输出>" + output_text.insert(tk.INSERT, text) + output_text.place(x=20, y=800, width=1390, height=80, anchor='sw') + # 进入消息循环 + root.mainloop() + + +if __name__ == '__main__': + # 创建主窗口 + root = tk.Tk() + w = root.winfo_screenwidth() + h = root.winfo_screenheight() + root.geometry("%dx%d" % (w, h)) + root.title("分形树 电脑的分辨率是%dx%d" % (root.winfo_screenwidth(), root.winfo_screenheight())) + root.geometry('1270x650') + root.title('分形树') + # 创建新增分形图案类型所需的字典 + str_params_dict = {} + pattern_dict = {} + tree_dict = {} + update_params_dict = {} + # 定义变量,用于存储用户选择的分形类型 + shape_var = tk.StringVar() + # 设置字体 + ft1 = tf.Font(family="黑体", size=21) + ft2 = tf.Font(family="黑体", size=21, weight=tf.BOLD) + ft3 = tf.Font(family="黑体", size=18) + ft4 = tf.Font(family="黑体", size=19) + # 创建一个标签 + lab1 = tk.Label(root, text="分形图案类型", font=ft1) + lab1.place(x=20, y=10, width=180, height=50, anchor='nw') + # 创建一个按钮,用来新增分形图案类型 + button_addPattern = tk.Button(root, text="新增分形图案类型", command=add_fractal, font=ft2) + button_addPattern.place(x=500, y=10, width=270, height=50, anchor='ne') + ## 滚动框的设置 + # 创建一个Canvas对象,使用该对象作为滚动区域 + canvas = tk.Canvas(root, width=445, height=160) + # 创建一个列表框对象Rlist,并将其放入滚动区域中 + Rlist = tk.Listbox(canvas, width=445, height=20, bg='white', highlightthickness=1, highlightbackground="LightBlue") + # 创建滚动条对象并与Canvas绑定,实现滚动条功能 + scrollbar = tk.Scrollbar(root, orient="vertical", command=canvas.yview) + canvas.configure(yscrollcommand=scrollbar.set) + canvas.place(x=20, y=75, anchor='nw') + scrollbar.place(x=470, y=75, width=30, height=160, anchor='nw') + # 创建一个Frame组件用于放置单选框 + frame = tk.Frame(Rlist, bg='white') + frame.place(anchor='nw') + # 将列表框放入Canvas中,并设置Canvas窗口的大小 + box_id = canvas.create_window((0, 0), window=Rlist, anchor="nw") + Rlist.update_idletasks() # 更新视图 + canvas.config(scrollregion=canvas.bbox("all")) # 设置画布的滚动区域 + # 添加单选框到 Frame组件 + rb_Y = tk.Radiobutton(frame, text="Y形分形 Y_Fractal", variable=shape_var, value='Y', bg="white", font=ft1) + rb_Y.pack(anchor='w') + rb_Triangle = tk.Radiobutton(frame, text="三角形分形 Triangle_Fractal", variable=shape_var, value='Triangle', + bg="white", font=ft1) + rb_Triangle.pack(anchor='w') + rb_Rect = tk.Radiobutton(frame, text="矩形分形 Rect_Fractal", variable=shape_var, value='Rect', bg="white", + font=ft1) + rb_Rect.pack(anchor='w') + if os.path.exists('params.csv'): + df = pd.read_csv("params.csv") + for i in df["分型名称"]: + rb1 = tk.Radiobutton(frame, text=i, variable=shape_var, value=df[df['分型名称'] == i].分形英文.values[0], + bg="white", font=ft1) + rb1.pack(anchor='w') + + # 将默认选项设置为 Y 形分形 + rb_Y.select() + # 创建一个标签 + lab2 = tk.Label(root, text="分形参数设置【参数含义:参量名=参量值】", font=ft4) + lab2.place(x=20, y=255, width=490, height=40, anchor='nw') + # 大画布的宽度和高度变量,方便后期调整 + big_width = 880 + big_height = 690 + # 创建蓝色边框的大画布 + cv_big = tk.Canvas(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + cv_big.config(width=big_width, height=big_height) + cv_big.place(x=530, y=10, anchor='nw') + # 创建红色边框的小画布,宽高设置为大画布的1/4 + cv_small = tk.Canvas(cv_big, bg="white", highlightthickness=1, highlightbackground="tomato") + cv_small.config(width=big_width * 0.25, height=big_height * 0.25) + cv_small.place(x=0, y=big_height, anchor='sw') + # 创建一个多行文本框 + params_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + params_text.configure(font=ft3, spacing1=15) + params_text.place(x=20, y=300, width=480, height=310, anchor='nw') + # 初始化分形参数并输出 + params_str = params_Y + params_text.insert(tk.INSERT, params_str) + # trace追踪变量w模式,回调函数update_text + shape_var.trace('w', lambda *args, str_params_dict=str_params_dict: update_Text()) + # 创建四个按钮 + button_delete = tk.Button(root, text="删除\n选项", command=delete_rb, font=ft2) + button_delete.place(x=20, y=700, width=90, height=75, anchor='sw') + button_pattern = tk.Button(root, text="基本图\n案绘制", command=draw_pattern, font=ft2) + button_pattern.place(x=130, y=700, width=120, height=75, anchor='sw') + button_params = tk.Button(root, text="绘制参\n数设置", command=update_params, font=ft2) + button_params.place(x=270, y=700, width=120, height=75, anchor='sw') + button_drawTree = tk.Button(root, text="绘制", command=draw_tree, font=ft2) + button_drawTree.place(x=410, y=700, width=90, height=75, anchor='sw') + # 创建底部输出框 + output_text = tk.Text(root, bg="white", highlightthickness=1, highlightbackground="LightBlue") + output_text.configure(font=ft3, spacing1=8) + text = " 结果输出:<分形绘制参数的字符串形式输出>" + output_text.insert(tk.INSERT, text) + output_text.place(x=20, y=800, width=1390, height=80, anchor='sw') + # 进入消息循环 + root.mainloop() diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击.png new file mode 100644 index 0000000..a777579 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@2x.png new file mode 100644 index 0000000..109a8f0 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@3x.png new file mode 100644 index 0000000..2387377 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存-点击@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存.png new file mode 100644 index 0000000..e3f4e41 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存@2x.png new file mode 100644 index 0000000..57e1967 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/保存@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/保存@3x.png new file mode 100644 index 0000000..02226d7 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/保存@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击.png new file mode 100644 index 0000000..07ce408 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@2x.png new file mode 100644 index 0000000..65565e5 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@3x.png new file mode 100644 index 0000000..83ba382 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改-点击@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改.png new file mode 100644 index 0000000..7c526ae Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改@2x.png new file mode 100644 index 0000000..f0b507c Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改@3x.png new file mode 100644 index 0000000..c2d7196 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击.png new file mode 100644 index 0000000..0da15d9 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@2x.png new file mode 100644 index 0000000..8a02a93 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@3x.png new file mode 100644 index 0000000..732772e Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案-点击@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案.png new file mode 100644 index 0000000..7f047a8 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@2x.png new file mode 100644 index 0000000..8ab4e47 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@3x.png new file mode 100644 index 0000000..a49c1cd Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/修改分形图案@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击.png new file mode 100644 index 0000000..0c43d2c Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@2x.png new file mode 100644 index 0000000..37ed3cb Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@3x.png new file mode 100644 index 0000000..93825c9 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案-点击@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案.png new file mode 100644 index 0000000..42de685 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@2x.png new file mode 100644 index 0000000..c36aa55 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@3x.png new file mode 100644 index 0000000..8da148b Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/删除图案@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击.png new file mode 100644 index 0000000..ebf5b89 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@2x.png new file mode 100644 index 0000000..9a3fa26 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@3x.png new file mode 100644 index 0000000..fb6abe3 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量-点击@3x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量.png new file mode 100644 index 0000000..4828ec2 Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@2x.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@2x.png new file mode 100644 index 0000000..db2467d Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@2x.png differ diff --git a/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@3x.png b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@3x.png new file mode 100644 index 0000000..bf14c4f Binary files /dev/null and b/images/1027分形树按钮切图/1027分形树按钮切图/添加变量@3x.png differ diff --git a/images/test2.py b/images/test2.py new file mode 100644 index 0000000..70bfd39 --- /dev/null +++ b/images/test2.py @@ -0,0 +1,14 @@ +function_string = """ +def recursive_function(parameter): + if parameter <= 0: + return + print(parameter) + recursive_function(parameter - 1) +recursive_function(parameter) +""" + +# 定义参数字典 +params = {'parameter': 5} + +# 使用exec()执行函数字符串 +exec(function_string, params) diff --git a/images/上部背景.png b/images/上部背景.png new file mode 100644 index 0000000..da7ea9f Binary files /dev/null and b/images/上部背景.png differ diff --git a/images/上部背景@2x.png b/images/上部背景@2x.png new file mode 100644 index 0000000..5921c41 Binary files /dev/null and b/images/上部背景@2x.png differ diff --git a/images/上部背景@3x.png b/images/上部背景@3x.png new file mode 100644 index 0000000..d54492d Binary files /dev/null and b/images/上部背景@3x.png differ diff --git a/images/下部背景.png b/images/下部背景.png new file mode 100644 index 0000000..1883746 Binary files /dev/null and b/images/下部背景.png differ diff --git a/images/下部背景@2x.png b/images/下部背景@2x.png new file mode 100644 index 0000000..c2cefd6 Binary files /dev/null and b/images/下部背景@2x.png differ diff --git a/images/下部背景@3x.png b/images/下部背景@3x.png new file mode 100644 index 0000000..94f3088 Binary files /dev/null and b/images/下部背景@3x.png differ diff --git a/images/保存@3x.png b/images/保存@3x.png new file mode 100644 index 0000000..02226d7 Binary files /dev/null and b/images/保存@3x.png differ diff --git a/images/修改@3x.png b/images/修改@3x.png new file mode 100644 index 0000000..c2d7196 Binary files /dev/null and b/images/修改@3x.png differ diff --git a/images/修改分形图案@3x.png b/images/修改分形图案@3x.png new file mode 100644 index 0000000..a49c1cd Binary files /dev/null and b/images/修改分形图案@3x.png differ diff --git a/images/全览图.png b/images/全览图.png new file mode 100644 index 0000000..c5606ce Binary files /dev/null and b/images/全览图.png differ diff --git a/images/全览图@2x.png b/images/全览图@2x.png new file mode 100644 index 0000000..2ce41f8 Binary files /dev/null and b/images/全览图@2x.png differ diff --git a/images/全览图@3x.png b/images/全览图@3x.png new file mode 100644 index 0000000..e576635 Binary files /dev/null and b/images/全览图@3x.png differ diff --git a/images/删除图案-点击.png b/images/删除图案-点击.png new file mode 100644 index 0000000..0c43d2c Binary files /dev/null and b/images/删除图案-点击.png differ diff --git a/images/删除图案@3x.png b/images/删除图案@3x.png new file mode 100644 index 0000000..8da148b Binary files /dev/null and b/images/删除图案@3x.png differ diff --git a/images/勾选.png b/images/勾选.png new file mode 100644 index 0000000..c087e1c Binary files /dev/null and b/images/勾选.png differ diff --git a/images/勾选@2x.png b/images/勾选@2x.png new file mode 100644 index 0000000..a65d239 Binary files /dev/null and b/images/勾选@2x.png differ diff --git a/images/勾选@3x.png b/images/勾选@3x.png new file mode 100644 index 0000000..cf8fafa Binary files /dev/null and b/images/勾选@3x.png differ diff --git a/images/勾选选中.png b/images/勾选选中.png new file mode 100644 index 0000000..f7b3c69 Binary files /dev/null and b/images/勾选选中.png differ diff --git a/images/勾选选中@2x.png b/images/勾选选中@2x.png new file mode 100644 index 0000000..3f7f4f8 Binary files /dev/null and b/images/勾选选中@2x.png differ diff --git a/images/勾选选中@3x.png b/images/勾选选中@3x.png new file mode 100644 index 0000000..d87c533 Binary files /dev/null and b/images/勾选选中@3x.png differ diff --git a/images/基本图案绘制-点击.png b/images/基本图案绘制-点击.png new file mode 100644 index 0000000..9c88c7d Binary files /dev/null and b/images/基本图案绘制-点击.png differ diff --git a/images/基本图案绘制-点击@2x.png b/images/基本图案绘制-点击@2x.png new file mode 100644 index 0000000..5f8a366 Binary files /dev/null and b/images/基本图案绘制-点击@2x.png differ diff --git a/images/基本图案绘制-点击@3x.png b/images/基本图案绘制-点击@3x.png new file mode 100644 index 0000000..9818754 Binary files /dev/null and b/images/基本图案绘制-点击@3x.png differ diff --git a/images/基本图案绘制.png b/images/基本图案绘制.png new file mode 100644 index 0000000..ab9c48c Binary files /dev/null and b/images/基本图案绘制.png differ diff --git a/images/基本图案绘制@2x.png b/images/基本图案绘制@2x.png new file mode 100644 index 0000000..782aa3f Binary files /dev/null and b/images/基本图案绘制@2x.png differ diff --git a/images/基本图案绘制@3x.png b/images/基本图案绘制@3x.png new file mode 100644 index 0000000..3a69171 Binary files /dev/null and b/images/基本图案绘制@3x.png differ diff --git a/images/大背景.jpg b/images/大背景.jpg new file mode 100644 index 0000000..6a17300 Binary files /dev/null and b/images/大背景.jpg differ diff --git a/images/大背景@2x.jpg b/images/大背景@2x.jpg new file mode 100644 index 0000000..62b25c2 Binary files /dev/null and b/images/大背景@2x.jpg differ diff --git a/images/大背景@3x.jpg b/images/大背景@3x.jpg new file mode 100644 index 0000000..ce87768 Binary files /dev/null and b/images/大背景@3x.jpg differ diff --git a/images/底部结果输出文字背景.jpg b/images/底部结果输出文字背景.jpg new file mode 100644 index 0000000..a7ed0aa Binary files /dev/null and b/images/底部结果输出文字背景.jpg differ diff --git a/images/底部结果输出文字背景@2x.png b/images/底部结果输出文字背景@2x.png new file mode 100644 index 0000000..085d70b Binary files /dev/null and b/images/底部结果输出文字背景@2x.png differ diff --git a/images/底部结果输出文字背景@3x.png b/images/底部结果输出文字背景@3x.png new file mode 100644 index 0000000..0fb1291 Binary files /dev/null and b/images/底部结果输出文字背景@3x.png differ diff --git a/images/文字背景@3x.png b/images/文字背景@3x.png new file mode 100644 index 0000000..0c911a8 Binary files /dev/null and b/images/文字背景@3x.png differ diff --git a/images/新增分形图案类型-点击.png b/images/新增分形图案类型-点击.png new file mode 100644 index 0000000..cf00e88 Binary files /dev/null and b/images/新增分形图案类型-点击.png differ diff --git a/images/新增分形图案类型-点击@2x.png b/images/新增分形图案类型-点击@2x.png new file mode 100644 index 0000000..f2280cc Binary files /dev/null and b/images/新增分形图案类型-点击@2x.png differ diff --git a/images/新增分形图案类型-点击@3x.png b/images/新增分形图案类型-点击@3x.png new file mode 100644 index 0000000..49e1fd1 Binary files /dev/null and b/images/新增分形图案类型-点击@3x.png differ diff --git a/images/新增分形图案类型.png b/images/新增分形图案类型.png new file mode 100644 index 0000000..f26d52b Binary files /dev/null and b/images/新增分形图案类型.png differ diff --git a/images/新增分形图案类型@2x.png b/images/新增分形图案类型@2x.png new file mode 100644 index 0000000..784002c Binary files /dev/null and b/images/新增分形图案类型@2x.png differ diff --git a/images/新增分形图案类型@3x.png b/images/新增分形图案类型@3x.png new file mode 100644 index 0000000..e2fdfd3 Binary files /dev/null and b/images/新增分形图案类型@3x.png differ diff --git a/images/添加变量@3x.png b/images/添加变量@3x.png new file mode 100644 index 0000000..bf14c4f Binary files /dev/null and b/images/添加变量@3x.png differ diff --git a/images/画布设置-点击.png b/images/画布设置-点击.png new file mode 100644 index 0000000..0d14fcd Binary files /dev/null and b/images/画布设置-点击.png differ diff --git a/images/画布设置-点击@2x.png b/images/画布设置-点击@2x.png new file mode 100644 index 0000000..4a42e5d Binary files /dev/null and b/images/画布设置-点击@2x.png differ diff --git a/images/画布设置-点击@3x.png b/images/画布设置-点击@3x.png new file mode 100644 index 0000000..a5379bb Binary files /dev/null and b/images/画布设置-点击@3x.png differ diff --git a/images/画布设置.png b/images/画布设置.png new file mode 100644 index 0000000..25e6f01 Binary files /dev/null and b/images/画布设置.png differ diff --git a/images/画布设置@2x.png b/images/画布设置@2x.png new file mode 100644 index 0000000..e11c3c4 Binary files /dev/null and b/images/画布设置@2x.png differ diff --git a/images/画布设置@3x.png b/images/画布设置@3x.png new file mode 100644 index 0000000..9a891e9 Binary files /dev/null and b/images/画布设置@3x.png differ diff --git a/images/绘制-点击.png b/images/绘制-点击.png new file mode 100644 index 0000000..aec5fa1 Binary files /dev/null and b/images/绘制-点击.png differ diff --git a/images/绘制-点击@2x.png b/images/绘制-点击@2x.png new file mode 100644 index 0000000..0f97b04 Binary files /dev/null and b/images/绘制-点击@2x.png differ diff --git a/images/绘制-点击@3x.png b/images/绘制-点击@3x.png new file mode 100644 index 0000000..f834500 Binary files /dev/null and b/images/绘制-点击@3x.png differ diff --git a/images/绘制.png b/images/绘制.png new file mode 100644 index 0000000..1c20818 Binary files /dev/null and b/images/绘制.png differ diff --git a/images/绘制@2x.png b/images/绘制@2x.png new file mode 100644 index 0000000..402df5a Binary files /dev/null and b/images/绘制@2x.png differ diff --git a/images/绘制@3x.png b/images/绘制@3x.png new file mode 100644 index 0000000..18e3ba5 Binary files /dev/null and b/images/绘制@3x.png differ diff --git a/images/绘制参数更新-点击.png b/images/绘制参数更新-点击.png new file mode 100644 index 0000000..7a12ca3 Binary files /dev/null and b/images/绘制参数更新-点击.png differ diff --git a/images/绘制参数更新-点击@2x.png b/images/绘制参数更新-点击@2x.png new file mode 100644 index 0000000..63b7de2 Binary files /dev/null and b/images/绘制参数更新-点击@2x.png differ diff --git a/images/绘制参数更新-点击@3x.png b/images/绘制参数更新-点击@3x.png new file mode 100644 index 0000000..1a30ee0 Binary files /dev/null and b/images/绘制参数更新-点击@3x.png differ diff --git a/images/绘制参数更新.png b/images/绘制参数更新.png new file mode 100644 index 0000000..466c86d Binary files /dev/null and b/images/绘制参数更新.png differ diff --git a/images/绘制参数更新@2x.png b/images/绘制参数更新@2x.png new file mode 100644 index 0000000..b886719 Binary files /dev/null and b/images/绘制参数更新@2x.png differ diff --git a/images/绘制参数更新@3x.png b/images/绘制参数更新@3x.png new file mode 100644 index 0000000..61b4382 Binary files /dev/null and b/images/绘制参数更新@3x.png differ diff --git a/images/顶部窗口背景.png b/images/顶部窗口背景.png new file mode 100644 index 0000000..b2ea5b8 Binary files /dev/null and b/images/顶部窗口背景.png differ diff --git a/images/顶部窗口背景@2x.png b/images/顶部窗口背景@2x.png new file mode 100644 index 0000000..fdedeb4 Binary files /dev/null and b/images/顶部窗口背景@2x.png differ diff --git a/images/顶部窗口背景@3x.png b/images/顶部窗口背景@3x.png new file mode 100644 index 0000000..44487ea Binary files /dev/null and b/images/顶部窗口背景@3x.png differ diff --git a/rect.py b/rect.py new file mode 100644 index 0000000..128e23c --- /dev/null +++ b/rect.py @@ -0,0 +1,42 @@ +def Rect_Pattern(): + canvas.delete("all") # 清空画布 + canvas.create_rectangle(25, 30, 145, 140, outline='red', width=2) + + +def Rect_tree(depth, point1, point2, angle, canvas): + # 直线的旋转,point1是定点 + def rotate(point1, point2, angle): + x1, y1 = point1[0], point1[1] + x2, y2 = point2[0], point2[1] + x = x1 + (x2 - x1) * math.cos(math.radians(angle)) + (y2 - y1) * math.sin(math.radians(angle)) + y = y1 + (y2 - y1) * math.cos(math.radians(angle)) - (x2 - x1) * math.sin(math.radians(angle)) + point = (x, y) + # print(point) + return point + # 直线的缩放,point1是定点 + def zoom(point1, point2, ratio): + x1, y1 = point1[0], point1[1] + x2, y2 = point2[0], point2[1] + x = x1 + (x2 - x1) * ratio + y = y1 + (y2 - y1) * ratio + point = (x, y) + return point + point3 = rotate(point1, point2, 90) + point4 = rotate(point2, point1, 270) + # print(point1,point2,point3,point4) + # 画正方形 + canvas.create_polygon(point1, point2, point4, point3, fill="#d8e6f7", outline='white') + if depth == 0: + return + point = rotate(point3, point4, angle) # 旋转 + point = zoom(point3, point, math.cos(math.radians(angle))) # 缩放 + Rect_tree(depth - 1, point, point4, angle, canvas) # 画左枝 + Rect_tree(depth - 1, point3, point, angle, canvas) # 画右枝 + canvas.update() + sleep(0.001) + + +分形层数:finishLevel = 8 +左下点:leftPoint = (450, 510) +右下点:rightPoint = (550, 510) +初始角:initAngle = 45 \ No newline at end of file diff --git a/test2.py b/test2.py new file mode 100644 index 0000000..83fbb87 --- /dev/null +++ b/test2.py @@ -0,0 +1,46 @@ +import math +import tkinter as tk + +def hexagonal_fractal_tree(depth, length, angle, center, canvas): + """ + 绘制六边形 + :param depth: + :param length: + :param angle: + :param center: + :param canvas: + :return: + """ + if depth == 0: + return + end_x = center[0] + length * math.cos(math.radians(angle)) + end_y = center[1] - length * math.sin(math.radians(angle)) + canvas.create_line(center[0], center[1], end_x, end_y, fill='LightBlue4', width=2) + hexagon_points = [] + for i in range(6): + hexagon_x = end_x + length * math.cos(math.radians(60 * i)) + hexagon_y = end_y - length * math.sin(math.radians(60 * i)) + hexagon_points.extend([hexagon_x, hexagon_y]) + canvas.create_polygon(hexagon_points, outline='LightBlue4', fill='', width=2) + new_length = length * 0.7 + new_depth = depth - 1 + new_angle1 = angle + 30 + new_angle2 = angle - 30 + hexagonal_fractal_tree(new_depth, new_length, new_angle1, (end_x, end_y), canvas) + hexagonal_fractal_tree(new_depth, new_length, new_angle2, (end_x, end_y), canvas) + +window = tk.Tk() +window.title("Hexagonal Fractal Tree") +canvas = tk.Canvas(window, width=400, height=400, bg='white') +canvas.pack() + +# Set the initial parameters and start drawing the tree +initial_length = 100 +initial_angle = 90 # Start with a vertical trunk +initial_center = (200, 400) # Adjust the center as needed +initial_depth = 5 # You can change the depth + +hexagonal_fractal_tree(initial_depth, initial_length, initial_angle, initial_center, canvas) + +# Start the tkinter main loop +window.mainloop() diff --git a/tree_mysql.py b/tree_mysql.py index dc3142f..5c8aa40 100644 --- a/tree_mysql.py +++ b/tree_mysql.py @@ -7,11 +7,10 @@ def connect_To_database(): conn = pymysql.connect( host='localhost', user='root', - password='cyh0110', + password='123123', db='ec', charset='utf8' ) - # print('连接成功') return conn except pymysql.Error as e: print('连接失败!', e) @@ -20,19 +19,19 @@ def connect_To_database(): def insert_data(conn, insert_query, list_code): # 创建游标 cursor = conn.cursor() - # # 创建表 - # new_tree_code = ''' - # create table if not exists fractal( - # id int AUTO_INCREMENT primary key, - # name TEXT, - # fractal_e TEXT, - # params_initial TEXT, - # str_params TEXT, - # pattern TEXT, - # tree TEXT, - # update_tree TEXT) - # ''' - # cursor.execute(new_tree_code) + # 创建表 + new_tree_code = ''' + create table if not exists fractal( + id int AUTO_INCREMENT primary key, + name TEXT, + fractal_e TEXT, + params_initial TEXT, + str_params TEXT, + pattern TEXT, + tree TEXT, + update_tree TEXT) + ''' + cursor.execute(new_tree_code) # 执行插入语句 cursor.execute(insert_query, list_code) @@ -42,3 +41,4 @@ def insert_data(conn, insert_query, list_code): conn.close() # 关闭游标 cursor.close() + diff --git a/三角.py b/三角.py new file mode 100644 index 0000000..1231971 --- /dev/null +++ b/三角.py @@ -0,0 +1,5 @@ +分形层数:FinishLevel=8 +缩放比例:TreePercent=0.8 +初始点:InitPoint=(520, 650) +初始角:InitAngle=30 +初始长度:InitLong=170