Я работаю над графическим интерфейсом для автоматизации части конвейера моего проекта, используя Tkinter и ttk в Python 2.7. У меня есть главное окно Tk (), которое генерирует окно Toplevel () после нажатия кнопки «Автоопределение», а затем создает динамическую серию доступных только для чтения виджетов Entry при нажатии кнопки на основе списка молекулярных видов, определенных в других местах кода.
Моя проблема в том, что, хотя поля ввода действительно отображаются на основе обнаруженных видов, они не остаются заполненными названиями видов после завершения функции, которая их создала. Я подозреваю, что это потому, что виджеты не являются глобальными [или даже в рамках окна Tk ()], а скорее определяются только внутри функции. Однако я не могу создать их в блоке кода, где определено окно Tk (), поскольку необходимое количество полей ввода неизвестно до тех пор, пока не будет нажата кнопка (таким образом вызывая функцию, которая их создает).
Я включил ниже абстрактный блок кода, который показывает проблему, с которой я столкнулся. Извиняюсь, если это долго. Я пытался сократить это как можно больше. Комментарии, которые я включил в код, показывают мои мысли и догадки о том, что происходит. Он должен быть готов к запуску в Python 2.7; Я надеюсь, что единственными необходимыми изменениями в Python 3.x являются импортные модификации.
Мой вопрос заключается в том, что после того, как я динамически создал виджеты Entry внутри функции, которая вызывается из главного окна Tk (), и заполнил их текстом, как я могу предотвратить их удаление после завершения функции? Отказ от ответственности: я не программист (или даже в области компьютерных наук) по профессии, поэтому я сделаю все возможное, чтобы держаться за все технические детали, но мне, возможно, придется задать некоторые глупые вопросы.
from Tkinter import *
import ttk
from time import sleep
def update_list(manager, rows):
species_list = ['A','B','C','D']
del rows[1:]
for widget in manager.children.values():
widget.grid_forget()
if not species_list == ['']:
species_elem_list = []
for i, each in enumerate(species_list):
## Here I attempt to create a dynamic list of StringVars to attach to the Entry fields below, based on the contents of the species list.
species_elem_list.append(StringVar())
## Here I initialize the values of the elements of the Entry fields by setting the StringVar of each.
species_elem_list[i].set(each)
## I tried to attach the value of the StringVar (from the species list) to the Entry below, but when the program is run, the Entry does not stay populated.
temp_name = ttk.Entry(manager, textvariable=species_elem_list[i], state='readonly')
temp_color = ttk.Label(manager, text='data')
temp_row = [temp_name, temp_color]
rows.append(temp_row)
for row_number in range(len(rows)):
for column_number, each in enumerate(rows[row_number]):
each.grid(column=column_number, row=row_number)
each.grid()
manager.update()
sleep(3) ## Included so that the population of the fields can be observed before they depopulate.
## After this point, the update_list function terminates.
## When that happens, the Entry fields depopulate. How can I get them to persist after the function terminates?
root = Tk()
manager = ttk.Frame(root, padding='4 5 4 4')
manager.grid(column=0, row=0, sticky=NSEW)
name_label = ttk.Label(manager, text='Name')
color_label = ttk.Label(manager, text='RGB')
rows = [[name_label, color_label]]
options = ttk.Frame(root)
options.grid(sticky=NSEW)
detect_button = ttk.Button(options, text='Auto-Detect', command=lambda: update_list(manager,rows))
done_button = ttk.Button(options, text='Done', command=root.destroy)
detect_button.grid(column=0, row=0)
done_button.grid(column=1, row=0)
root.mainloop()
В идеале виджеты Entry должны оставаться (и оставаться заполненными!) После завершения функции update_list. Я также хочу иметь возможность взаимодействовать с содержимым этих виджетов извне функции.
В настоящее время поля Entry заполняются во время выполнения функции update_list, а затем сразу же заполняются после ее завершения. Я подозреваю, что это потому, что виджеты и их содержимое не являются глобальными по объему.