Tkinter Entry.get()不更新问题(Gurobi Python线性规划场景)
问题诊断与修复方案
我帮你排查了代码里的问题,核心问题出在模型变量的作用域和参数传递逻辑上,导致你始终在求解旧模型(约束右端值保持初始的0)。下面是具体分析和修复后的代码:
问题根源
- 模型变量
m的作用域错误:你在build_model函数内部创建了局部的m,但后续的m.optimize()、results()等操作调用的是全局的m——这个全局m从未被更新,一直是初始状态(或未定义的旧模型)。 - 参数传递逻辑冗余:虽然
setEntryValue()更新了全局的entryValue,但build_model构建的新模型没有关联到后续操作的m上,等于白搭。
修复后的完整代码
import Tkinter as tk from gurobipy import * WIDTH = 330 HEIGHT = 500 root = tk.Tk() canvas = tk.Canvas(root, height=HEIGHT, width=WIDTH) canvas.pack() # 初始化全局变量 m = None # 全局模型变量,后续会被每次构建的新模型覆盖 entryValue = 0 var = tk.IntVar(value=0) # 给输入框设置初始值0 # UI元素定义 conslabel = tk.Label(root, text='Constraint value') conslabel.place(relx=0.1, rely=0.02) entry = tk.Entry(root, textvariable=var) entry.place(relx=0.5, rely=0.02, relwidth=0.3) outputLabel = tk.Label(root, bg='white') outputLabel.place(relx=0.5, rely=0.85, anchor=tk.CENTER, relheight=0.2, relwidth=0.8) def setEntryValue(): global entryValue entryValue = var.get() return entryValue def build_model(): global m # 创建新模型,覆盖全局变量m,确保后续操作的是最新模型 m = Model("lp1") m.setParam('OutputFlag', False) x1 = m.addVar(name="x1") x2 = m.addVar(name="x2") m.update() # 设置目标函数 m.setObjective(5*x1 + 4*x2, GRB.MAXIMIZE) # 添加约束,这里直接使用已更新的全局entryValue m.addConstr(6*x1 + 4*x2 <= 24, "constr_1") m.addConstr(1*x1 + 2*x2 <= 6, "constr_2") m.addConstr(-1*x1 + 1*x2 <= 1, "constr_3") m.addConstr(x2 <= entryValue, "constr_4") def labeltext(): global m finalvars = '' for v in m.getVars(): if v.x != 0: finalvars += ' ' + str(v.varName) return finalvars if finalvars else 'No non-zero variables' def results(): global m # 控制台打印结果(方便调试) for v in m.getVars(): print('%s: %f' % (v.varName, v.x)) print('Obj: %f' % m.objVal) # 更新UI标签显示 outputLabel['text'] = labeltext() # 按钮点击逻辑:按顺序执行更新值→构建新模型→优化→显示结果→重置模型 button = tk.Button(root, text="yield result", command=lambda: [setEntryValue(), build_model(), m.optimize(), results(), m.reset()]) button.place(relx=0.5, rely=0.675, anchor=tk.CENTER) root.mainloop()
关键修改说明
- 全局模型变量
m:在全局作用域初始化m,并在build_model中用global m声明使用全局变量,每次点击按钮都会创建新模型并覆盖m,确保后续操作的是最新的模型。 - 简化参数传递:
build_model不再需要接收参数,直接使用被setEntryValue()更新后的全局entryValue,逻辑更清晰。 - 健壮性优化:给
labeltext添加了无零变量时的提示文本,避免UI显示空内容;同时给IntVar设置了初始值,让输入框默认显示0。
现在你输入新的约束值点击按钮,程序会构建包含新约束的模型,求解后就能正确显示非零变量了!
内容的提问来源于stack exchange,提问作者floschen
相关产品推荐
相关产品推荐

