ИСПРАВЛЕНИЕ TLDR: поместите свои объекты (или список объектов) в словарь
Проще говоря, я динамически создаю кучу страниц в блокноте wxpython, и на каждой странице я размещаю дополнительные виджеты, сайзеры и тому подобное. моя проблема в том, что если я хочу получить доступ к переменной, установленной в цикле for, когда он создает страницу, я не могу этого сделать, потому что после повторного запуска цикла for переменная будет сброшена и использована для заполнения новой страницы.
что-то в этом роде
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((400, 300))
self.notebook_1 = wx.Notebook(self, wx.ID_ANY)
self.text_button = wx.Button(self, wx.ID_ANY, "get text")
self.Bind(wx.EVT_BUTTON, self.get_text_handler, self.text_button)
self.__set_properties()
sizer_1 = wx.BoxSizer(wx.VERTICAL)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1.Add(self.text_button, 0, 0, 0)
sizer_1.Add(self.notebook_1, 1, wx.EXPAND, 0)
self.SetSizer(sizer_1)
self.Layout()
numlist = (1, 2, 3, 4)
#global page_dictionary
#page_dictionary = {}
for i in numlist:
self.notebook_1_pane_2 = wx.Panel(self.notebook_1, wx.ID_ANY)
self.notebook_1_pane_2.SetSizer(sizer_2)
self.notebook_1.AddPage(self.notebook_1_pane_2, str(i))
self.label_1 = wx.TextCtrl(self.notebook_1_pane_2, wx.ID_ANY, str(i))
sizer_2.Add(self.label_1, 0, 0, 0)
self.Layout()
#page_k = self.label_1.GetValue()
#page_k_good = page_k + str(i)
#page_dictionary[page_k_good] = i
#print(page_dictionary)
def __set_properties(self):
self.SetTitle("frame")
def get_text_handler(self, event): # wxGlade: MyFrame.<event_handler>
print(self.label_1.GetValue())
единственная разница между этим и тем, что я на самом деле запускаю, заключается в том, что переменная numlist фактически генерирует случайное число значений динамически.
моя проблема в том, что если я хочу сослаться на любую из меток, установленных на предыдущих страницах, я не могу, потому что переменная self.label_1 сбрасывается до записи на последней странице. поэтому, если я хочу получить доступ к метке, скажем, на странице номер 1, для переменной метки устанавливаются значения последней страницы, созданной в цикле for. это похоже на то, что после того, как метка была размещена и заполнена на странице wxNotebook, она просто исчезла, и то, что находится в этом виджете, больше недоступно.
так как бы я, например, распечатал (self.label_1) страницы 1 в блокноте, когда self.label_1 был переписан, чтобы соответствовать метке на последней сгенерированной странице?
возился со словарями, поэтому я прокомментировал это. как я могу нажать эту кнопку и получить текст из полей на текущих страницах?
Окончательное редактирование, надеюсь:
как бы я мог назначить несколько объектов в словарь? нужно ли мне просто присвоить значение i в виде списка (label_1, Label_2), а затем, когда нужно вызвать для них методы, просто сослаться на них из списка, который теперь находится в словаре?
ага, сделал это, поместил их в словарь в виде списка, может вытащить список, когда это необходимо.
Это первый раз, когда я когда-либо возился с чем-то подобным, и я понятия не имею, как даже начать это делать. есть ли способ добавить переменную i к именам переменных при генерации? поэтому self.label_1 станет self.label_1(i) и в конечном итоге станет self.label_11, self.label_12, self.label13 и т. д., чтобы я мог легко ссылаться на них после генерации?
Я все еще не понимаю, что именно вы пытаетесь сделать, но, основываясь на обоснованном предположении, я думаю, что вы пытаетесь сохранить идентичность объектов, созданных в цикле, чтобы к ним можно было получить доступ вне цикла. Имея это в виду, вот пример того, как это можно сделать. Вот очень упрощенный пример:
import random as rnd #used to create a random number for each object
# just a list of names to be scanned in for loop
lst = ["a", "b", "c", "d"]
# Just an illustrative object for demo purposes
class SillyClass:
def __init__(self, name, nmb):
self._id = name
self._nmb = nmb
@property
def name(self):
return self._id
@property
def number(self):
return self._nmb
# create a list of objects for later reference
def build_objects(lst):
rslt = []
for itm in lst:
rslt.append(SillyClass(itm, rnd.randrange(5, 200)))
return rslt
# show use of list to print object data
obj_lst = build_objects(lst)
# Show the contents of obj_lst
print(obj_lst, "\n")
# show access of object attributes
for obj in obj_lst:
print(f"Object: {obj.name} contains {obj.number}")
Результат выполнения этого кода:
[<__main__.SillyClass object at 0x0000022C5CB9E9D0>, <__main__.SillyClass object at 0x0000022C5CB9EFD0>, <__main__.SillyClass object at 0x0000022C5CB9E670>, <__main__.SillyClass object at 0x0000022C5CC42370>]
Object: a contains 187
Object: b contains 164
Object: c contains 97
Object: d contains 52
Это показывает, что obj_lst содержит список объектов, который затем можно использовать для доступа к атрибутам объекта. Вы можете использовать этот подход или, возможно, связать объект с определенным идентификатором, используя структуру dict. Все, что вам нужно, чтобы наилучшим образом служить вашим целям.
в основном я назначаю textctrl каждой странице блокнота в wxpython, но я не могу вернуть то, что в данный момент находится в этих textctrls, потому что переменная, которой они назначены, заменяется каждый раз, когда цикл повторяется. возможно ли вообще взаимодействовать с виджетом на странице блокнота, который был создан динамически, или это просто сумасшедшая концепция
я обновил код с помощью textctrls, о котором я говорил
Если вы хотите получить доступ к виджетам, создайте словарь, где ключом является имя переменной или просто целое число, а значением является созданный объект виджета. Пример: {1:widget_object1, 2:widget_object2, . . . .}
В вашем цикле замените page_dictionary[page_k_good] = i
на page_dictionary[i] = self.label_1
Теперь page_dictionary содержит каждый из определенных self_label_1, проиндексированных индексом страницы.
сладкий, мой последний вопрос: как я собираюсь получить доступ к этим объектам для получения информации, можете ли вы вызывать методы для объектов, которые находятся в словаре?
что вы можете. Например, допустим, вам нужно значение виджета self.label_1 на странице 4, вы просто выполните следующее: v = page_dictionary[4].GetValue()
Это замечательно! чувак, ой намного эффективнее. что, если в цикле создается более одного объекта? метка_1 И метка_2
что, если в цикле создается более одного объекта? метка_1 И метка_2? я не уверен, как добавить их в словарь, не могу использовать только словарь [i] = label_1, потому что вам также нужно добавить label_2
создайте список виджетов, которые будут добавлены на страницу, тогда значение словаря для страницы будет просто списком виджетов. Затем вы можете получить доступ к каждому виджету в зависимости от его порядка в списке.
ДА, все разобрался и теперь работает, БОЛЬШОЕ СПАСИБО! это мой первый опыт в ООП, и я действительно не знал, что вы можете просто хранить целые объекты в списке (а затем в последующих словарях). полностью изменить правила игры
ой, видите, вы уже сделали. Рад, что помог.
Основываясь на том, что, как я думаю, вы говорите, вы динамически создаете серию страниц в блокноте, используя цикл for. На каждой странице вы размещаете ряд виджетов. Ваша проблема в том, что после того, как вы завершили цикл для определенной страницы, вы больше не можете ссылаться на содержимое этой страницы, потому что номер теперь ссылается на другую страницу. Пожалуйста, отредактируйте свой вопрос, чтобы показать минимальный воспроизводимый набор. См. Минимальный воспроизводимый пример для получения подробной информации о том, как лучше всего помочь нам помочь вам.