当前位置: 首页 > 知识库问答 >
问题:

破坏tkinter mainloop(带画布和按钮),奇怪的行为

谷光誉
2023-03-14

我有root=Tk。Tk()由标签(Tk.Label)、条目表单(Tk.entry)、按钮(Tk.button)和嵌入式matplotlib图CAVASTKAGG组成。这是一个简单的脚本,它用用户指定的系数(a,b,c)绘制四层函数。但是我在破坏主循环时遇到了一些问题和误解。我原以为,简单地关闭主窗口(通过单击右角的“x”)也会导致退出mainloop。如果我要注释与嵌入画布相关的所有代码,那么我的脚本就是这样。但对于嵌入式FigureCastKagg,它不会发生(因此需要中断内核以再次运行脚本)。正如在其他问题中所讨论的,退出mainloop有两种方法:root。退出()根目录。销毁()。因此,我也尝试使用这些方法退出mainloop:

def close_all():
    root.quit()
    root.destroy()

通过“新建”按钮:

button_quit=Tk.Button(root, text="Quit", command=close_all)
button_quit.grid(row=5, column=1)

通过覆盖"x"按钮:

root.protocol('WM_DELETE_WINDOW', close_all)

我的问题:

>

  • 使用这两种方法都有效。但是为什么如果我只使用root.destroy()root.mainloop()仍然会执行?为什么主循环不会在关闭窗口后被破坏?以及为什么这个问题会导致Fig reCanvasTkAgg?嵌入matplotlib图由以下步骤完成(如果有助于解释):

    fig, ax = plt.subplots()
    canvas = FigureCanvasTkAgg(fig, master=root)
    plot_widget = canvas.get_tk_widget()
    #(plotting with plt.plot(..))
    canvas.show()
    plot_widget.grid(row=6, column = 0, columnspan=3)
    

    close_all()函数就是在这个意义上工作的,即执行了退出mainloop,脚本执行停止。但还是有一些奇怪的行为。有一些变量,例如var\u a=Tk。StringVar(),用于以以下方式从输入字段接收数据:

    L_a = Tk.Label(master=root, width=10, height=2, bd =2, text="a")
    E_a = Tk.Entry(master=root, width=10, bd =2, textvariable=var_a) 
    

    具有

    def get_value():
        if not check_if_float(var_a.get()) or not check_if_float(var_b.get()) or not check_if_float(var_c.get()):
            showerror(title = "Error", message = "Invalid entry. Enter integer or decimal numbers, please")
            return None
        a=float(var_a.get())
        b=float(var_b.get())
        c=float(var_c.get())
    

    因此,问题和奇怪的行为是,在执行一次代码后,并关闭主窗口(通过单击右上角的x,或通过单击退出按钮),在下一个执行代码接收空的var_a,var_b,var_c。如果内核中断,并且代码再次运行,它将正常工作(在jupyter笔记本中运行)。我不知道为什么会这样。

  • 共有1个答案

    高修筠
    2023-03-14

    这是因为您没有为变量提供主变量,所以它们默认为创建的第一个Tk()实例,即使它已被销毁。修复方法只是提供正确的根目录:

    var_a = Tk.StringVar(root)
    

    这通常不是问题,因为很少有情况下需要多次调用Tk()。

     类似资料:
    • 问题内容: 我要点击的部分: 我想很简单。但是我似乎丢失了一些东西。 现在,问题在页面的下方进行了更新。 xpath并不是我尝试使用更正后的xpath的问题,它与使用类名相同。CSS隐藏了该按钮的多个版本,但是在它实际上使用xpath或类名找到的按钮上抛出了common.exception。 我检查了页面是否已正确加载,并且元素在那里。我有一个检查要等到整个页面加载完毕并确定它的屏幕截图。 给出:

    • 我正在创建一个视图,允许我绘制给定的位图。 当我创建画布时,我将位图作为它的基础。它在模拟器上工作得很好,但是当我试图在手机上使用它时,它表现得很奇怪,并将位图旋转了90度。 以下是我创建画布的方式。我从以前的活动中获得正确的。 这里是截图 谢谢你的帮助,我不习惯于画布,所以我有点迷路了:/

    • 矩形填充的图像改变其比例(宽度和高度改变)。 这显示了转换前后的svg。 有没有人有办法解决这个问题?

    • 问题内容: 好吧,这种特定的布局让我很烦。而且似乎找不到找到listView的方法,在底部有一行按钮,这样listview不会延伸到按钮的上方,因此这些按钮始终固定在屏幕的底部。这就是我想要的: 删除了死的ImageShack链接 似乎应该这么简单,但是我尝试过的所有方法都失败了。有什么帮助吗? 这是我当前的代码: 问题答案: 我认为这就是您想要的。

    • 我试图理解编译器在这里抱怨的原因: 使用编译时生成的消息 如下: cexpr_test.cpp:在函数 'int main()' 中: cexpr_test.cpp:12:76: error: 'const std::initializer_list{((const char* const*)( 令人困惑的是,为什么它会毫无问题地构造第一个初始值设定项列表。我在这里缺少什么?

    • 问题内容: 谁能解释,为什么ES6阵列解构会发生以下情况? 问题答案: 正如其他人所说,您缺少分号。但… 谁能解释? 其中 是预期的解构任务 是一个赋值表达式,将数组分配到左侧,并对数组求值 是对数组文字的属性引用 正在使用逗号运算符,计算结果为(是) 如果你想省略分号,让那里的人永远自动插入 可能 需要的话,你将需要把一个在开始每一行的是开头,,,,或```。