Tkinter毕业设计:基于Combobox选中值控制Canvas风险矩阵内棋子移动求助
解决方案
核心问题梳理
- 原
move_image函数的非空判断逻辑错误,仅校验了可能性下拉框的取值不为空,未正确校验影响下拉框的取值 - 无需写24个if分支判断坐标,可提前预设每个影响等级、可能性等级对应的棋盘坐标,通过字典直接取值即可,逻辑更简洁不易出错
- 原代码中满足首个if条件就触发return,直接终止了函数执行,导致后续的棋子移动逻辑不会运行
- 你给
tk.Canvas打补丁新增的abs_move方法多传了冗余的canvas参数,方法内部的self本身就是当前Canvas实例 - 原代码存在笔误:导入ttk时误写为
tkk,重复导入tkinter模块
预设坐标规则说明
你可以根据自己的矩阵网格实际尺寸调整下面的坐标映射,这里我们假设影响等级1-5对应X轴坐标依次递增,可能性等级1-5对应Y轴坐标依次递增,你可以自行替换映射值适配你的矩阵图片:
# 影响等级对应X坐标,可根据实际网格调整 impact_x_map = {1: 100, 2: 180, 3: 260, 4: 340, 5: 420} # 可能性等级对应Y坐标,可根据实际网格调整 likelihood_y_map = {1: 380, 2: 300, 3: 220, 4: 140, 5: 60}
修正后完整代码
import tkinter as tk from PIL import Image, ImageTk from tkinter import ttk def abs_move(self, _object, new_x, new_y, speed=10): # 获取棋子当前位置 x, y, *_ = self.bbox(_object) # 移动到目标位置 self.move(_object, new_x-x, new_y-y) # 给Canvas打补丁新增绝对移动方法 tk.Canvas.abs_move = abs_move def on_button_pressed(event): global canvas global chesspiece start_x = canvas.canvasx(event.x) start_y = canvas.canvasy(event.y) print("start_x, start_y =", start_x, start_y) # 根据下拉框取值移动棋子 def move_image(): global canvas global chesspiece global totalvalues # 正确判断两个下拉框都有取值 if combo_impact.get() != '' and combo_likelihood.get() != '': # 获取对应的等级值 impact_level_val = impactDict[combo_impact.get()] likelihood_level_val = likelihoodDict[combo_likelihood.get()] totalvalues = impact_level_val * likelihood_level_val # 获取对应的坐标 target_x = impact_x_map[impact_level_val] target_y = likelihood_y_map[likelihood_level_val] # 移动棋子 canvas.abs_move(chesspiece, target_x, target_y) # 风险等级判断可在这里统一写,不用每个分支都return if totalvalues <= 3: risk_tip = "可忽略风险" elif totalvalues <= 8: risk_tip = "低风险" elif totalvalues <= 15: risk_tip = "中风险" else: risk_tip = "高风险" print(risk_tip) total.configure(text="风险评分 : " + str(totalvalues)) # 等级映射字典 impactDict = {'灾难性': 5, '严重': 4, '较大': 3, '中等': 2, '轻微':1} likelihoodDict = {'几乎确定': 5, '很可能': 4, '可能': 3, '不太可能': 2, '罕见':1} # 坐标映射字典,可根据你的矩阵实际尺寸调整数值 impact_x_map = {1: 100, 2: 180, 3: 260, 4: 340, 5: 420} likelihood_y_map = {1: 380, 2: 300, 3: 220, 4: 140, 5: 60} root = tk.Tk() root.geometry("1356x750") root.state("zoomed") root.configure(bg='Dodgerblue4') canvas = tk.Canvas(root, width=650, height=450,bg="black") canvas.grid(row=3, column=5, pady=20) button = tk.Button(root, text="计算风险", command=move_image) button.grid(row=2, column=0) # 注意替换成你自己的矩阵图片路径 img2 = ImageTk.PhotoImage(file="65.png") image_on_canvas = canvas.create_image(0, 0, image=img2, anchor='nw') canvas.bind("<Button-1>", on_button_pressed) # 注意替换成你自己的棋子图片路径 risklevel = ImageTk.PhotoImage(file="king5.png") chesspiece= canvas.create_image(93,302,image=risklevel) tk.Label(root, text='法律风险影响程度', bd=3, bg='Dodgerblue4', fg='white').grid(row=0, column=0) var_impact = tk.StringVar() combo_impact = ttk.Combobox(root, values=list(impactDict.keys()), justify="center", textvariable=var_impact) combo_impact.bind("<<ComboboxSelected>>", lambda event: impact_level.config(text=impactDict[var_impact.get()])) combo_impact.grid(row=0, column=1) combo_impact.current(0) impact_level = tk.Label(root, text="", bg='Dodgerblue4', fg='white') impact_level.grid(row=0, column=2, padx=10) tk.Label(root, text='法律风险发生概率', bd=3, bg='Dodgerblue4', fg='white').grid(row=1, column=0) var_likelihood = tk.StringVar() combo_likelihood = ttk.Combobox(root, values=list(likelihoodDict.keys()), justify="center", textvariable=var_likelihood) combo_likelihood.bind("<<ComboboxSelected>>", lambda event: likelihood_level.config(text=likelihoodDict[var_likelihood.get()])) combo_likelihood.grid(row=1, column=1) combo_likelihood.current(0) likelihood_level = tk.Label(root, text="", bg='Dodgerblue4', fg='white') likelihood_level.grid(row=1, column=2, padx=10) totalvalues = '无' total = tk.Label(root,text="", bg='Dodgerblue4', fg='white' ) total.grid(row=2, column=1, padx=5, pady=5) root.mainloop()
调整说明
点击画布上的矩阵格子,控制台会打印对应的坐标,把这些坐标替换到impact_x_map和likelihood_y_map里对应的等级位置,就能适配你自己的风险矩阵图片尺寸。
内容的提问来源于stack exchange,提问作者henoker
相关产品推荐
相关产品推荐

