diff --git a/myprogram.py b/myprogram.py new file mode 100644 index 0000000..7215df4 --- /dev/null +++ b/myprogram.py @@ -0,0 +1,634 @@ +import tkinter as tk +from tkinter import filedialog +from tkinter import messagebox +import cv2 +import numpy as np +from PIL import Image, ImageTk + + +class MyApp: + def __init__(self, root): + # 三个frame从左到右分别放置原图,结果图,控制台,标为123 + self.frame1 = None + self.frame2 = None + self.frame3 = None + self.src = None # 原始图像 + # self.src = cv2.imread("fxe.png") + self.image = None # 结果输出图像 + self.src2 = None # 二元运算的第二张图 + self.tem_img = None # 临时保存本地的图片 + + # UI设置 + self.root = root + self.root.title("简易数字图像处理系统") + self.root.state('zoomed') # 窗口最大化 + # 获取窗口大小,得到窗口大小(减去底部任务栏的高度) + self.width = root.winfo_screenwidth() + self.height = root.winfo_screenheight() - 71 + # frame12的宽高 + self.fwidth = int(self.width * 7 / 16) + self.fheight = self.height + # console控制台的宽高 + self.cwidth = int(self.width * 2 / 16) + self.cheight = self.height + + self.create_widget() # 布置组件 + # 布置菜单 + self.menu_bar = tk.Menu(root) + root.config(menu=self.menu_bar) + self.create_menu() + + def create_widget(self): + # 布置组件 + self.frame1 = tk.Frame(root, width=self.fwidth, height=920, bd=2, relief="ridge") + self.frame2 = tk.Frame(root, width=self.fwidth, height=920, bd=2, relief="ridge") + self.frame3 = tk.Frame(root, width=1600 - 2 * self.fwidth, height=920, bd=2, relief="ridge") + self.frame1.place(x=0, y=0, anchor="nw") + self.frame2.place(x=self.fwidth, y=0, anchor="nw") + self.frame3.place(x=2 * self.fwidth, y=0, anchor="nw") + label1 = tk.Label(self.frame1, text="原始图像", font=("宋体", 30)) + label1.place(x=self.fwidth / 2 - 100, y=15, anchor="nw") + label2 = tk.Label(self.frame2, text="输出图像", font=("宋体", 30)) + label2.place(x=self.fwidth / 2 - 100, y=15, anchor="nw") + label3 = tk.Label(self.frame3, text="控制台", font=("宋体", 30)) + label3.place(x=self.cwidth / 2 - 60, y=15, anchor="nw") + self.src_panel = tk.Label(self.frame1, image=None) + self.img_panel = tk.Label(self.frame2, image=None) + + def create_menu(self): + # 布置菜单 + self.menu_bar.add_cascade(label="加载图片", command=self.load_src) + self.menu_bar.add_cascade(label="加载输出图像", command=self.load_image_use_src) + + self.file_menu = tk.Menu(self.menu_bar, tearoff=0) + self.file_menu.add_command(label="灰化", command=self.convert_to_gray) + self.file_menu.add_command(label="算术运算", command=self.arithmetic_calculation) + self.file_menu.add_command(label="缩放旋转图像", command=self.rotate_image) + self.file_menu.add_command(label="翻转", command=self.flip_image) + self.file_menu.add_command(label="仿射变换", command=self.affine_transform) + self.file_menu.add_command(label="对数变换", command=self.logarithmic_transform) + self.file_menu.add_command(label="线性变换", command=self.linear_transform) + self.file_menu.add_command(label="直方图均衡化", command=self.equalizehist) + self.file_menu.add_command(label="开运算", command=self.open) + self.file_menu.add_command(label="闭运算", command=self.close) + self.menu_bar.add_cascade(label="处理图像", menu=self.file_menu) + + self.menu_bar.add_cascade(label="保存图片", command=self.save_image) + + def load_image(self): + # 加载本地图片至self.tem_img + file_path = filedialog.askopenfilename() + if len(file_path) > 0: + image = cv2.imread(file_path, cv2.IMREAD_COLOR) + self.tem_img = image + + def load_src(self): + # 加载原始图片并显示 + self.load_image() + self.src = self.tem_img + self.clear_frame1() + self.clear_frame23() + self.display_image(self.src, self.frame1) + + def load_image_use_src(self): + # 把输出图像加载到原始图像并显示 + if self.image is not None: + self.src = self.image + self.clear_frame1() + self.display_image(self.src, self.frame1) + else: + messagebox.showerror("Error", "没有输出图像") + + def display_image(self, image, frame): + # 将opencv格式的image显示到frame(1或2) + panel = tk.Label(frame, image=None) + # 将opencv的图片转换成PIL格式,并等比例适配frame大小 + img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + img = Image.fromarray(img) + width, height = img.size + rwidth, rheight = 0, 0 + q = width / height + # 下面将fheight-200是为了空出上下文字的空间 + if q > self.fwidth / (self.fheight - 220): # 图片较宽的情况 + rwidth = self.fwidth + rheight = 1 / q * self.fwidth + panel.place(x=0, y=self.fheight / 2 - rheight / 2, anchor="nw") + else: # 图片较高的情况 + rheight = self.fheight - 175 + rwidth = q * rheight + panel.place(x=self.fwidth / 2 - rwidth / 2, y=60, anchor="nw") + img = img.resize((int(rwidth), int(rheight))) + img = ImageTk.PhotoImage(img) + panel.configure(image=img) + panel.image = img + + # 显示图片大小 + height, width = image.shape[:2] # image是传进来的opencv格式的图片 + width_lab = tk.Label(frame, text=f"宽度:{width}", font=("宋体", 18)) + width_lab.place(x=self.fwidth / 2 - 100, y=self.fheight - 110, anchor="nw") + height_lab = tk.Label(frame, text=f"高度:{height}", font=("宋体", 18)) + height_lab.place(x=self.fwidth / 2 - 100, y=self.fheight - 60, anchor="nw") + + def clear_frame1(self): + for widget in self.frame1.winfo_children(): + widget.destroy() + label = tk.Label(self.frame1, text="原始图像", font=("宋体", 30)) + label.place(x=self.fwidth / 2 - 100, y=15, anchor="nw") + + def clear_frame2(self): + for widget in self.frame2.winfo_children(): + widget.destroy() + label = tk.Label(self.frame2, text="输出图像", font=("宋体", 30)) + label.place(x=self.fwidth / 2 - 100, y=15, anchor="nw") + + def clear_frame23(self): + # 清楚frame23上的所有组件 + self.src2 = None + for widget in self.frame3.winfo_children(): + widget.destroy() + label3 = tk.Label(self.frame3, text="控制台", font=("宋体", 30)) + label3.place(x=self.cwidth / 2 - 60, y=15, anchor="nw") + for widget in self.frame2.winfo_children(): + widget.destroy() + label2 = tk.Label(self.frame2, text="输出图像", font=("宋体", 30)) + label2.place(x=self.fwidth / 2 - 100, y=15, anchor="nw") + + def save_image(self): + # 保存图片至本地 + if self.image is not None: + file_path = filedialog.asksaveasfilename(defaultextension=".jpg", + filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png")], + initialfile="image.jpg") + if file_path: + cv2.imwrite(file_path, self.image) + else: + messagebox.showerror("Error", "没有输出图像") + + def convert_to_gray(self): + # 灰化图片 + if self.src is not None: + self.clear_frame23() + self.image = cv2.cvtColor(self.src, cv2.COLOR_BGR2GRAY) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + def arithmetic_calculation(self): + # 算术运算 + def add(): + if self.src2 is not None: + height, width = self.src.shape[:2] + src2 = cv2.resize(self.src2, (int(width), int(height))) + self.image = cv2.add(self.src, src2) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + def subtract(): + if self.src2 is not None: + height, width, _ = self.src.shape + src2 = cv2.resize(self.src2, (int(width), int(height))) + self.image = cv2.subtract(self.src, src2) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + def multiply(): + if self.src2 is not None: + height, width, _ = self.src.shape + src2 = cv2.resize(self.src2, (int(width), int(height))) + img = cv2.subtract(self.src, src2) + image1_float = np.float32(self.src) + image2_float = np.float32(img) + result = cv2.multiply(image1_float, image2_float) + self.image = np.uint8(result) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + def button(): + self.load_image() + self.src2 = self.tem_img + + label = tk.Label(self.frame3, image=None) + img = cv2.cvtColor(self.src2, cv2.COLOR_BGR2RGB) + img = Image.fromarray(img) + width, height = img.size + rwidth, rheight = 0, 0 + q = width / height + if q > self.cwidth / 400: # 图片较宽的情况 + rwidth = self.cwidth + rheight = 1 / q * self.cwidth + label.place(x=0, y=325 - rheight / 2, anchor="nw") + else: + rheight = 400 + rwidth = q * 400 + label.place(x=(1600 - 2 * self.fwidth) / 2 - rwidth / 2, y=100, anchor="nw") + img = img.resize((int(rwidth), int(rheight))) + img = ImageTk.PhotoImage(img) + + label.configure(image=img) + label.image = img + + if self.src is not None: + self.clear_frame23() + load_but = tk.Button(self.frame3, text="加载第二张图", font=("宋体", 18), command=button) + load_but.place(x=self.cwidth / 2 - 75, y=100, anchor="nw") + load_a = tk.Button(self.frame3, text="加法运算", font=("宋体", 18), command=add) + load_a.place(x=self.cwidth / 2 - 60, y=500, anchor="nw") + load_s = tk.Button(self.frame3, text="减法运算", font=("宋体", 18), command=subtract) + load_s.place(x=self.cwidth / 2 - 60, y=600, anchor="nw") + load_m = tk.Button(self.frame3, text="乘法运算", font=("宋体", 18), command=multiply) + load_m.place(x=self.cwidth / 2 - 60, y=700, anchor="nw") + + else: + messagebox.showerror("Error", "未加载图像") + + def rotate_image(self): + # 旋转图像 + def button(): + try: + angle = int(angel_en.get()) # 旋转角度,可以根据需要调整 + scale = float(scale_en.get()) + except ValueError: + messagebox.showerror("Error", "输入异常,请输入数字") + height, width = self.src.shape[:2] + center = (width // 2, height // 2) + rotation_matrix = cv2.getRotationMatrix2D(center, angle, scale) + + cos = np.abs(rotation_matrix[0, 0]) + sin = np.abs(rotation_matrix[0, 1]) + new_width = int((height * sin) + (width * cos)) + new_height = int((height * cos) + (width * sin)) + + # 调整旋转矩阵的平移部分 + rotation_matrix[0, 2] += (new_width / 2) - center[0] + rotation_matrix[1, 2] += (new_height / 2) - center[1] + + # 进行仿射变换 + self.image = cv2.warpAffine(self.src, rotation_matrix, (new_width, new_height)) + self.display_image(self.image, self.frame2) + + if self.src is not None: + self.clear_frame23() + angel_lab = tk.Label(self.frame3, text="旋转角度", font=("宋体", 18)) + angel_lab.place(x=10, y=100, anchor="nw") + angel_lab2 = tk.Label(self.frame3, text="(整数)", font=("宋体", 18)) + angel_lab2.place(x=90, y=150, anchor="nw") + angel_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + angel_en.place(x=110, y=100, anchor="nw") + angel_en.insert(0, "0") + scale_lab = tk.Label(self.frame3, text="缩放因子", font=("宋体", 18)) + scale_lab.place(x=10, y=200, anchor="nw") + scale_lab = tk.Label(self.frame3, text="(小数)", font=("宋体", 18)) + scale_lab.place(x=90, y=250, anchor="nw") + scale_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + scale_en.place(x=110, y=200, anchor="nw") + scale_en.insert(0, "1") + but = tk.Button(self.frame3, text="运算", font=("宋体", 18), command=button) + but.place(x=self.cwidth / 2 - 40, y=300, anchor="nw") + + + else: + messagebox.showerror("Error", "未加载图像") + + def flip_image(self): + # 翻转图像 + def horizontal(): + self.image = cv2.flip(self.src, 1) + self.display_image(self.image, self.frame2) + + def vertical(): + self.image = cv2.flip(self.src, 0) + self.display_image(self.image, self.frame2) + + def cross(): + self.image = cv2.flip(self.src, -1) + self.display_image(self.image, self.frame2) + + if self.src is not None: + self.clear_frame23() + h_but = tk.Button(self.frame3, text="水平翻转", font=("宋体", 18), command=horizontal) + h_but.place(x=self.cwidth / 2 - 60, y=100, anchor="nw") + v_but = tk.Button(self.frame3, text="垂直翻转", font=("宋体", 18), command=vertical) + v_but.place(x=self.cwidth / 2 - 60, y=200, anchor="nw") + c_but = tk.Button(self.frame3, text="对角翻转", font=("宋体", 18), command=cross) + c_but.place(x=self.cwidth / 2 - 60, y=300, anchor="nw") + + else: + messagebox.showerror("Error", "未加载图像") + + def affine_transform(self): + def get_coordinates(entry, size): + coordinates = entry.get().split(',') # 英文逗号 + if len(coordinates) != 2: + coordinates = entry.get().split(',') # 中文逗号 + if len(coordinates) != 2: + coordinates = entry.get().split(' ') + if len(coordinates) != 2: + messagebox.showerror("Error", "请输入正确的坐标格式,如:x,y") + return -1, -1 + + try: + x, y = int(coordinates[0]), int(coordinates[1]) + if x > size[0] or y > size[1]: + messagebox.showerror("Error", "坐标必须在图像内") + else: + return x, y + except ValueError: + messagebox.showerror("Error", "坐标必须为整数") + return -1, -1 + + def check(): + return get_coordinates(p1_en, size)[0] != -1 and get_coordinates(p2_en, size)[0] != -1 and \ + get_coordinates(p3_en, size)[0] != -1 and get_coordinates(p4_en, size)[0] != -1 and \ + get_coordinates(p5_en, size)[0] != -1 and get_coordinates(p6_en, size)[0] != -1 + + def show(): + tmp = self.src.copy() + size = tmp.shape[:2] + if check(): + radius = int(max(size[0], size[1]) / 100) + cv2.circle(tmp, get_coordinates(p1_en, size), radius, (255, 0, 0), -1) + cv2.circle(tmp, get_coordinates(p2_en, size), radius, (0, 255, 0), -1) + cv2.circle(tmp, get_coordinates(p3_en, size), radius, (0, 0, 255), -1) + cv2.circle(tmp, get_coordinates(p4_en, size), radius, (255, 0, 0), -1) + cv2.circle(tmp, get_coordinates(p5_en, size), radius, (0, 255, 0), -1) + cv2.circle(tmp, get_coordinates(p6_en, size), radius, (0, 0, 255), -1) + self.clear_frame2() + self.display_image(tmp, self.frame2) + + def button(): + if check(): + self.clear_frame2() + post1 = np.float32([get_coordinates(p1_en, size), get_coordinates(p2_en, size), get_coordinates(p3_en, size)]) + post2 = np.float32([get_coordinates(p4_en, size), get_coordinates(p5_en, size), get_coordinates(p6_en, size)]) + M = cv2.getAffineTransform(post1, post2) + + self.image = cv2.warpAffine(self.src, M, self.src.shape[:2]) + self.display_image(self.image, self.frame2) + + if self.src is not None: + self.clear_frame23() + size = self.src.shape[:2] + try_but = tk.Button(self.frame3, text="显示", font=("宋体", 18), command=show) + try_but.place(x=self.cwidth / 2 - 40, y=150, anchor="nw") + p1_lab = tk.Label(self.frame3, text="原始点1", font=("宋体", 18)) + p1_lab.place(x=10, y=200, anchor="nw") + p1_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p1_en.place(x=100, y=200, anchor="nw") + p1_en.insert(0, "50 50") + p2_lab = tk.Label(self.frame3, text="原始点2", font=("宋体", 18)) + p2_lab.place(x=10, y=250, anchor="nw") + p2_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p2_en.place(x=100, y=250, anchor="nw") + p2_en.insert(0, "200 50") + p3_lab = tk.Label(self.frame3, text="原始点3", font=("宋体", 18)) + p3_lab.place(x=10, y=300, anchor="nw") + p3_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p3_en.place(x=100, y=300, anchor="nw") + p3_en.insert(0, "50 200") + p4_lab = tk.Label(self.frame3, text="目标点1", font=("宋体", 18)) + p4_lab.place(x=10, y=350, anchor="nw") + p4_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p4_en.place(x=100, y=350, anchor="nw") + p4_en.insert(0, "10 100") + p5_lab = tk.Label(self.frame3, text="目标点2", font=("宋体", 18)) + p5_lab.place(x=10, y=400, anchor="nw") + p5_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p5_en.place(x=100, y=400, anchor="nw") + p5_en.insert(0, "200 50") + p6_lab = tk.Label(self.frame3, text="目标点3", font=("宋体", 18)) + p6_lab.place(x=10, y=450, anchor="nw") + p6_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p6_en.place(x=100, y=450, anchor="nw") + p6_en.insert(0, "100 250") + but = tk.Button(self.frame3, text="运算", font=("宋体", 18), + command=button) + but.place(x=self.cwidth / 2 - 40, y=500, anchor="nw") + + + else: + messagebox.showerror("Error", "未加载图像") + + def logarithmic_transform(self): + # 对数变换 + if self.src is not None: + self.clear_frame23() + img=cv2.cvtColor(self.src, cv2.COLOR_BGR2GRAY) + C = 255 / np.log(1 + 255) + result = C * np.log(1.0 + img) + self.image = np.uint8(result+0.5) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + def linear_transform(self): + # 线性变换 + + def get_range(entry): + range = entry.get().split(',') # 英文逗号 + if len(range) != 2: + range = entry.get().split(',') # 中文逗号 + if len(range) != 2: + range = entry.get().split(' ') + if len(range) != 2: + messagebox.showerror("Error", "请输入正确的范围格式,如:x,y") + return -1, -1 + + try: + x, y = int(range[0]), int(range[1]) + if 0 > x or 255 < y: + messagebox.showerror("Error", "范围必须在(0,255)内") + else: + return x, y + except ValueError: + messagebox.showerror("Error", "坐标必须为整数") + return -1, -1 + + def check(): + return get_range(p1_en)[0] != -1 and get_range(p2_en)[0] != -1 + + def button(): + if check(): + self.clear_frame2() + img = cv2.cvtColor(self.src, cv2.COLOR_BGR2GRAY) + a,b=get_range(p1_en) + c,d=get_range(p2_en) + result = (d - c) / (b - a) * img + (b * c - a * d) / (b - a) + self.image = np.uint8(result + 0.5) + self.display_image(self.image, self.frame2) + + if self.src is not None: + self.clear_frame23() + + p1_lab = tk.Label(self.frame3, text="原始区间", font=("宋体", 18)) + p1_lab.place(x=10, y=200, anchor="nw") + p1_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p1_en.place(x=110, y=200, anchor="nw") + p1_en.insert(0, "50 100") + p2_lab = tk.Label(self.frame3, text="目标区间", font=("宋体", 18)) + p2_lab.place(x=10, y=250, anchor="nw") + p2_en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + p2_en.place(x=110, y=250, anchor="nw") + p2_en.insert(0, "0 255") + but = tk.Button(self.frame3, text="运算", font=("宋体", 18), + command=button) + but.place(x=self.cwidth / 2 - 40, y=300, anchor="nw") + + else: + messagebox.showerror("Error", "未加载图像") + + def equalizehist(self): + # 灰化图片 + if self.src is not None: + self.clear_frame23() + img = cv2.cvtColor(self.src,cv2.COLOR_BGR2GRAY) + self.image = cv2.equalizeHist(img) + self.display_image(self.image, self.frame2) + else: + messagebox.showerror("Error", "未加载图像") + + + + + def open(self): + selected_real_value = cv2.MORPH_CROSS + def get_size(entry,size): + range = entry.get().split(',') # 英文逗号 + if len(range) != 2: + range = entry.get().split(',') # 中文逗号 + if len(range) != 2: + range = entry.get().split(' ') + if len(range) != 2: + messagebox.showerror("Error", "请输入正确的范围格式,如:x,y") + return -1, -1 + try: + x, y = int(range[0]), int(range[1]) + if x<0 or y<0 or x>size[0] or y>size[1]: + messagebox.showerror("Error", "范围必须在图像内") + else: + return x, y + except ValueError: + messagebox.showerror("Error", "坐标必须为整数") + return -1, -1 + def button(): + kernel = cv2.getStructuringElement(selected_real_value, get_size(en,self.src.shape[:2])) + self.image = cv2.morphologyEx(self.src, cv2.MORPH_OPEN, kernel) + self.display_image(self.image, self.frame2) + def on_option_selected(*args): + option_value_map = { + "交叉": cv2.MORPH_CROSS, + "椭圆": cv2.MORPH_ELLIPSE, + "矩形": cv2.MORPH_RECT + } + nonlocal selected_real_value + selected_text = selected_value.get() + selected_real_value = option_value_map[selected_text] + + if self.src is not None: + self.clear_frame23() + + lab = tk.Label(self.frame3, text="结构元", font=("宋体", 18)) + lab.place(x=10, y=100, anchor="nw") + en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + en.place(x=100, y=100, anchor="nw") + en.insert(0, "5 5") + + framet=tk.Frame(self.frame3) + options = [ + "交叉", + "椭圆", + "矩形" + ] + + # 创建一个变量来存储用户选择的显示文本 + selected_value = tk.StringVar(root) + selected_value.set(options[0]) + + option_menu = tk.OptionMenu(framet, selected_value, *options, command=on_option_selected) + option_menu.pack() + framet.place(x=self.cwidth / 2 - 40, y=200, anchor="nw") + + + but = tk.Button(self.frame3, text="运算", font=("宋体", 18), + command=button) + but.place(x=self.cwidth / 2 - 40, y=500, anchor="nw") + + + else: + messagebox.showerror("Error", "未加载图像") + + + def close(self): + selected_real_value = cv2.MORPH_CROSS + def get_size(entry,size): + range = entry.get().split(',') # 英文逗号 + if len(range) != 2: + range = entry.get().split(',') # 中文逗号 + if len(range) != 2: + range = entry.get().split(' ') + if len(range) != 2: + messagebox.showerror("Error", "请输入正确的范围格式,如:x,y") + return -1, -1 + try: + x, y = int(range[0]), int(range[1]) + if x<0 or y<0 or x>size[0] or y>size[1]: + messagebox.showerror("Error", "范围必须在图像内") + else: + return x, y + except ValueError: + messagebox.showerror("Error", "坐标必须为整数") + return -1, -1 + def button(): + kernel = cv2.getStructuringElement(selected_real_value, get_size(en,self.src.shape[:2])) + self.image = cv2.morphologyEx(self.src, cv2.MORPH_CLOSE, kernel) + self.display_image(self.image, self.frame2) + def on_option_selected(*args): + option_value_map = { + "交叉": cv2.MORPH_CROSS, + "椭圆": cv2.MORPH_ELLIPSE, + "矩形": cv2.MORPH_RECT + } + nonlocal selected_real_value + selected_text = selected_value.get() + selected_real_value = option_value_map[selected_text] + + if self.src is not None: + self.clear_frame23() + + lab = tk.Label(self.frame3, text="结构元", font=("宋体", 18)) + lab.place(x=10, y=100, anchor="nw") + en = tk.Entry(self.frame3, width=5, font=("宋体", 18)) + en.place(x=100, y=100, anchor="nw") + en.insert(0, "5 5") + + framet=tk.Frame(self.frame3) + options = [ + "交叉", + "椭圆", + "矩形" + ] + + # 创建一个变量来存储用户选择的显示文本 + selected_value = tk.StringVar(root) + selected_value.set(options[0]) + + option_menu = tk.OptionMenu(framet, selected_value, *options, command=on_option_selected) + option_menu.pack() + framet.place(x=self.cwidth / 2 - 40, y=200, anchor="nw") + + + but = tk.Button(self.frame3, text="运算", font=("宋体", 18), + command=button) + but.place(x=self.cwidth / 2 - 40, y=500, anchor="nw") + + + else: + messagebox.showerror("Error", "未加载图像") + + +if __name__ == '__main__': + root = tk.Tk() + app = MyApp(root) + root.mainloop()