【问题标题】:Changing grid position with a button in python使用python中的按钮更改网格位置
【发布时间】:2020-03-12 00:42:54
【问题描述】:

我正在尝试使单选按钮更改输入字段的位置(称为分配)

我期望它在按钮旁边将其网格化,但我得到了这个错误

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1702, in __call__
    return self.func(*args)
  File "<string>", line 16, in <lambda>
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 2223, in grid_configure
    + self._options(cnf, kw))
_tkinter.TclError: bad window path name ".!application.!entry"`

问题出在第 16 行的 lambda 函数

我尝试在函数中创建变量,我也尝试让它运行 exec。

这里是代码

from tkinter import *
import random
class application(Frame):
    def __init__(self,master ):
        Frame.__init__(self, master)
        self.grid()
        self.create_widgets()
    def create_widgets(self, ):
        assignment = Entry(self)

        for i in self.winfo_children():
            i.destroy()
        self.var = IntVar()
        for i in range(8):
            Radiobutton(self, text = ('class ' + str(i + 1)), variable = self.var, value = (i+1), command = lambda i = i: assignment.grid()).grid(row = i, column = 1)
        for i in range(8):
            exec('class' + str(i) + ' = Label(self, text = \'34\')\nclass' + str(i) + '.grid(row = '+str(i)+',column =  3)')

        print(self.var.get())

root = Tk()
root.title('dumb kid idiot test')
root.geometry('500x500')
app = application(root)
root.mainloop()

【问题讨论】:

  • 你对 lambda 中的 i 什么都不做。也永远不要像这样使用exec
  • @Mike-SMT 你知道有什么更好的方法来做那个高管正在做的事情

标签: python tkinter radio-button grid-layout


【解决方案1】:

我不确定您为什么要使用 exec 创建标签。有一种更安全的方法来执行此操作,就像您的 raidiobutton 一样。

您遇到的一个主要问题是您没有使用您在 lambda 中定义的i。如果您不将该值应用于网格,则无法更新任何内容。

此外,此代码会立即破坏您的输入字段。

for i in self.winfo_children():
    i.destroy()

我稍微清理了您的示例并修复了 lambda 问题。

试试这个:

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry('300x225')
        self.title('dumb kid idiot test')

        self.entry = tk.Entry(self)
        self.var = tk.IntVar(self)

        for i in range(8):
            tk.Radiobutton(self, text=('class ' + str(i + 1)), variable=self.var, value=(i+1),
                           command=lambda i=i: self.entry.grid(row=i, column=4)).grid(row=i, column=1)
        for i in range(8):
            tk.Label(self, text='34').grid(row=i, column=3)


if __name__ == '__main__':
    App().mainloop()

您可能还需要一个函数/方法来处理网格机会,以防万一您还希望您的按钮在单击时执行其他操作。

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry('300x225')
        self.title('dumb kid idiot test')

        self.entry = tk.Entry(self)
        self.var = tk.IntVar(self)
        for i in range(8):
            tk.Radiobutton(self, text=('class ' + str(i + 1)), variable=self.var, value=(i+1),
                           command=lambda i=i: self.move_entry(i)).grid(row=i, column=1)
        for i in range(8):
            tk.Label(self, text='34').grid(row=i, column=3)

    def move_entry(self, ndex):
        self.entry.grid(row=ndex, column=4)


if __name__ == '__main__':
    App().mainloop()

【讨论】:

  • 谢谢你的兄弟,我傻了,忘了我正在清理窗户
【解决方案2】:

让我们看看这段代码:

def create_widgets(self, ):
    assignment = Entry(self)

    for i in self.winfo_children():
        i.destroy()

您正在创建一个条目小部件,然后您几乎立即将其删除,因为它是 self 的子小部件。因此,以后尝试使用或修改小部件的任何代码都将失败,并显示您给出的确切错误。

如果您打算使用该条目,请不要删除它。您可以通过以下几种方式做到这一点:

  • 您可以在循环中添加显式检查,这样您就不会在条目小部件上调用 delete,
  • 不要循环遍历所有子级,而是将要销毁的小部件保存在一个列表中,然后遍历该列表而不是所有子级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-01
    • 2013-10-27
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-04
    相关资源
    最近更新 更多