Изменение положения сетки с помощью кнопки в python - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь заставить переключатели переключать положение поля ввода (называемое назначением)

, что я ожидал, чтобы оно расположило его рядом с кнопкой, но вместо этого я получаю эту ошибку

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 с лямбда-функцией

я пытался создать переменную в функции, я также пытался запустить ее exe c.

вот код

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()

Ответы [ 2 ]

0 голосов
/ 11 марта 2020

Давайте посмотрим на этот код:

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

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

Вы создаете виджет записи, а затем почти сразу удаляете его, так как он является дочерним для self. Поэтому любой код, который позже попытается использовать или изменить виджет, завершится с ошибкой, которую вы ему сообщаете.

Если вы планируете использовать запись, не удаляйте ее. Вы можете сделать это несколькими способами:

  • Вы можете добавить явную проверку в l oop, чтобы не вызывать delete в виджете ввода,
  • Вместо того, чтобы зацикливаться на всех дочерних элементах, сохраняйте виджеты, которые вы хотите уничтожить, в списке и повторяйте этот список вместо всех дочерних элементов.
0 голосов
/ 11 марта 2020

Я не уверен, почему вы используете exec для создания ярлыка. Есть гораздо более безопасный способ сделать это, точно так же, как ваша raidiobutton.

Одна из ваших основных проблем - вы не используете i, который вы определили в своей лямбде. Ничто не может быть обновлено, если вы не примените это значение к сетке.

Также этот код сразу уничтожает ваше поле ввода.

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

Я немного почистил ваш пример и исправил лямбда-проблема.

Попробуйте это:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...