ZuiLiuaB 7a729b728d
Update work.py
Add button + -
2025-05-07 12:00:37 +08:00

176 lines
6.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import tkinter as tk
from tkinter import filedialog, messagebox
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
from scipy.interpolate import make_interp_spline
from PIL import Image
import io
# 更新输入框值的函数,支持整型和浮点型
def update_entry_value(entry, delta, is_integer=False):
try:
value = float(entry.get()) + delta
if is_integer:
value = int(round(value)) # 确保为整数
entry.delete(0, tk.END)
entry.insert(0, str(value))
except ValueError:
pass
def generate_and_display_shape():
try:
min_vertices = int(min_entry.get())
max_vertices = int(max_entry.get())
line_width = float(line_width_entry.get())
scatter = float(scatter_entry.get())
if min_vertices < 3 or max_vertices < 3 or min_vertices > max_vertices:
messagebox.showerror("无效输入", "最小和最大顶点数必须至少为3并且最小值不应超过最大值。")
return
ax.clear()
num_vertices = np.random.randint(min_vertices, max_vertices + 1)
angles = np.sort(np.random.rand(num_vertices) * 2 * np.pi)
angles += np.random.normal(0, scatter, num_vertices)
angles = np.sort(angles % (2 * np.pi))
x = np.cos(angles)
y = np.sin(angles)
x = np.append(x, x[0])
y = np.append(y, y[0])
t = np.linspace(0, 1, num_vertices + 1)
t_smooth = np.linspace(0, 1, 300)
spl_x = make_interp_spline(t, x, k=3)
spl_y = make_interp_spline(t, y, k=3)
x_smooth = spl_x(t_smooth)
y_smooth = spl_y(t_smooth)
global current_line
if current_line:
current_line.remove()
current_line, = ax.plot(x_smooth, y_smooth, linestyle='-', color='gray', linewidth=line_width)
ax.axis('equal')
ax.axis('off')
canvas.draw()
except ValueError:
messagebox.showerror("无效输入", "请输入有效的整数作为最小和最大顶点数,以及浮点数作为线的粗细和散布。")
def adjust_line_width():
try:
line_width = float(line_width_entry.get())
if current_line:
current_line.set_linewidth(line_width)
canvas.draw()
except ValueError:
messagebox.showerror("无效输入", "请输入有效的浮点数作为线的粗细。")
def save_shape():
buf = io.BytesIO()
plt.savefig(buf, format='png', transparent=True)
buf.seek(0)
image = Image.open(buf).convert("RGBA")
file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG 文件", "*.png"), ("所有文件", "*.*")])
if file_path:
image.save(file_path)
messagebox.showinfo("保存成功", f"图像已保存到 {file_path}")
# 创建主窗口
root = tk.Tk()
root.title("随机封闭形状生成器-醉流ab")
root.geometry("800x700")
# 创建Matplotlib图形
fig, ax = plt.subplots(figsize=(5, 5), dpi=100)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
# 创建输入框和按钮的框架
input_frame = tk.Frame(root)
input_frame.pack(side=tk.TOP, padx=30, pady=30)
# 线的粗细控制
line_width_label = tk.Label(input_frame, text="线的粗细:")
line_width_label.grid(row=0, column=0, padx=10, pady=10, sticky="e")
line_width_entry = tk.Entry(input_frame, width=8)
line_width_entry.insert(0, "1.0")
line_width_entry.grid(row=0, column=1, padx=10, pady=10)
# 线的粗细 +/- 按钮(只调整线宽)
tk.Button(input_frame, text="-", width=3,
command=lambda: [update_entry_value(line_width_entry, -0.1), adjust_line_width()]
).grid(row=0, column=0, sticky="w")
tk.Button(input_frame, text="+", width=3,
command=lambda: [update_entry_value(line_width_entry, 0.1), adjust_line_width()]
).grid(row=0, column=1, sticky="e")
# 散布控制
scatter_label = tk.Label(input_frame, text="散布:")
scatter_label.grid(row=0, column=2, padx=10, pady=10, sticky="e")
scatter_entry = tk.Entry(input_frame, width=8)
scatter_entry.insert(0, "0.1")
scatter_entry.grid(row=0, column=3, padx=10, pady=10)
# 散布 +/- 按钮(刷新图形)
tk.Button(input_frame, text="-", width=3,
command=lambda: [update_entry_value(scatter_entry, -0.01), generate_and_display_shape()]
).grid(row=0, column=2, sticky="w")
tk.Button(input_frame, text="+", width=3,
command=lambda: [update_entry_value(scatter_entry, 0.01), generate_and_display_shape()]
).grid(row=0, column=3, sticky="e")
# 调整按钮
adjust_button = tk.Button(input_frame, text="调整", command=adjust_line_width, width=10, height=2)
adjust_button.grid(row=0, column=4, padx=10, pady=10)
# 最小顶点数控制
min_label = tk.Label(input_frame, text=" 最小顶点数 (>3):")
min_label.grid(row=1, column=0, padx=10, pady=10, sticky="e")
min_entry = tk.Entry(input_frame, width=8)
min_entry.insert(0, "10")
min_entry.grid(row=1, column=1, padx=10, pady=10)
# 最小顶点数 +/- 按钮(刷新图形)
tk.Button(input_frame, text="-", width=3,
command=lambda: [update_entry_value(min_entry, -1, is_integer=True), generate_and_display_shape()]
).grid(row=1, column=0, sticky="w")
tk.Button(input_frame, text="+", width=3,
command=lambda: [update_entry_value(min_entry, 1, is_integer=True), generate_and_display_shape()]
).grid(row=1, column=1, sticky="e")
# 最大顶点数控制
max_label = tk.Label(input_frame, text=" 最大顶点数:")
max_label.grid(row=1, column=2, padx=10, pady=10, sticky="e")
max_entry = tk.Entry(input_frame, width=8)
max_entry.insert(0, "15")
max_entry.grid(row=1, column=3, padx=10, pady=10)
# 最大顶点数 +/- 按钮(刷新图形)
tk.Button(input_frame, text="-", width=3,
command=lambda: [update_entry_value(max_entry, -1, is_integer=True), generate_and_display_shape()]
).grid(row=1, column=2, sticky="w")
tk.Button(input_frame, text="+", width=3,
command=lambda: [update_entry_value(max_entry, 1, is_integer=True), generate_and_display_shape()]
).grid(row=1, column=3, sticky="e")
# 刷新按钮
refresh_button = tk.Button(input_frame, text="刷新", command=generate_and_display_shape, width=10, height=2)
refresh_button.grid(row=1, column=4, padx=10, pady=10)
# 保存按钮
save_button = tk.Button(input_frame, text="保存", command=save_shape, width=10, height=2)
save_button.grid(row=1, column=5, padx=10, pady=10)
# 初始化图形
current_line = None
generate_and_display_shape()
# 运行主循环
root.mainloop()