Я пытаюсь создать графический интерфейс с большим количеством элементов, где есть несколько наборов одной и той же вещи (шесть ярлыков и шесть радиобокс).
Что я хочу сделать (чтобы сэкономить место и опыт обучения) - создать какой-то цикл для размещения этих элементов на панели, которую я использую.
На самом деле их размещение должно быть легким, но кикер, мне нужно, чтобы все они были уникальны, поэтому я могу индивидуально изменить каждую метку или получить каждое значение каждого радиоблока в отдельности.
Ниже приведен код, который я имею прямо сейчас, где все элементы индивидуально созданы и размещены.
sizerMain = wx.BoxSizer()
## For the main control area
panelControl = wx.Panel(self,1,style = wx.MAXIMIZE)
sizerControl = wx.GridBagSizer(hgap = 4,vgap = 4)
# Add widgets
## Main content area
lblTitle = wx.StaticText(panelControl,label = "Pick Scores")
sizerControl.Add(lblTitle,pos = (0,0),
flag = wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.BOTTOM,
border = 5)
self.btnRoll = wx.Button(panelControl,label = "Roll!")
sizerControl.Add(self.btnRoll,pos = (0,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 5)
### Radio boxes
#### Radio button tuple
rboxPick = ["Default","Strength","Dexterity","Constitution",
"Intelligence","Wisdom","Charisma"]
self.lblRoll1 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll1,pos = (1,0),flag = wx.ALIGN_CENTER)
self.rboxRoll1 = wx.RadioBox(panelControl,label = "Roll One",choices = rboxPick)
sizerControl.Add(self.rboxRoll1,pos = (1,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.lblRoll2 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll2,pos = (2,0),flag = wx.ALIGN_CENTER)
self.rboxRoll2 = wx.RadioBox(panelControl,label = "Roll Two",choices = rboxPick)
sizerControl.Add(self.rboxRoll2,pos = (2,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.lblRoll3 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll3,pos = (3,0),flag = wx.ALIGN_CENTER)
self.rboxRoll3 = wx.RadioBox(panelControl,label = "Roll Three",choices = rboxPick)
sizerControl.Add(self.rboxRoll3,pos = (3,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.lblRoll4 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll4,pos = (4,0),flag = wx.ALIGN_CENTER)
self.rboxRoll4 = wx.RadioBox(panelControl,label = "Roll Four",choices = rboxPick)
sizerControl.Add(self.rboxRoll4,pos = (4,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.lblRoll5 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll5,pos = (5,0),flag = wx.ALIGN_CENTER)
self.rboxRoll5 = wx.RadioBox(panelControl,label = "Roll Five",choices = rboxPick)
sizerControl.Add(self.rboxRoll5,pos = (5,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.lblRoll6 = wx.StaticText(panelControl)
sizerControl.Add(self.lblRoll6,pos = (6,0),flag = wx.ALIGN_CENTER)
self.rboxRoll6 = wx.RadioBox(panelControl,label = "Roll Six",choices = rboxPick)
sizerControl.Add(self.rboxRoll6,pos = (6,1),span = (1,5),
flag = wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
Кроме того, поздно. Итак, если я не понимаю смысла, дайте мне знать, и я буду рад снова объяснить.
Прошло некоторое время с тех пор, как я сделал какое-либо кодирование wxPython, поэтому я немного ржавый, но, с самого начала, я могу думать о двух способах сделать это, кроме решения нейрино, хотя есть и другие варианты.
Метод 1
Сохраняйте ссылки на каждый виджет в словаре, используя метку виджетов в качестве ключа, например
rboxPick = ["Default", "Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma"]
labels = ["One", "Two", "Three", "Four"]
self.rollRbs = dict()
#create the radioBoxes..
for row, label in enumerate(labels):
lbl = wx.StaticText(panelControl)
rbox = wx.RadioBox(panelControl, label="Roll %s"%(label),
choices=rboxPick)
sizerControl.Add(rbox ,pos = (row, 1),span=(1,5),
flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border = 2)
self.rollRbs[rbox.GetLabel()] = rbox
#changing the label...
self.rollRbs["Roll One"].SetLabel("blah")
Метод 2
Лично я предпочитаю более управляемый событиями подход. Просто привяжите каждое событие RadioBoxes
к тому же обработчику. Затем в обработчике вы можете различать RadioBoxes
с помощью своих атрибутов метки.
Рабочий пример:
import wx
class GUI(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(700, 400))
panelControl = wx.Panel(self, 1, style=wx.MAXIMIZE)
sizerControl = wx.GridBagSizer(hgap=4,vgap = 4)
lblTitle = wx.StaticText(panelControl, label="Pick Scores")
self.btnRoll = wx.Button(panelControl, label="Roll!")
sizerControl.Add(lblTitle, pos=(0,0),
flag=wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.BOTTOM, border=5)
sizerControl.Add(self.btnRoll, pos=(0,1),
span=(1,5), flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)
rboxPick = ["Default", "Strength", "Dexterity", "Constitution",
"Intelligence", "Wisdom", "Charisma"
]
labels = ["One", "Two", "Three", "Four"]
#Create, layout and bind the RadioBoxes
for row, label in enumerate(labels):
lbl = wx.StaticText(panelControl)
rbox = wx.RadioBox(panelControl, label="Roll %s"%(label), choices=rboxPick)
self.Bind(wx.EVT_RADIOBOX, self.onRadioBox, rbox)
sizerControl.Add(rbox, pos=(row+1, 1), span=(1,5),
flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=2)
sizerMain = wx.BoxSizer()
sizerMain.Add(sizerControl)
panelControl.SetSizerAndFit(sizerMain)
def onRadioBox(self, evt):
"""Event handler for RadioBox.."""
rbox = evt.GetEventObject()#Get a reference to the RadioBox
rboxLbl = rbox.GetLabel() #We can identify the RadioBox with its label
selection = rbox.GetSelection()
print rboxLbl
print selection
if rboxLbl == "Roll One":
#do something
pass
elif rboxLbl == "Roll Two":
#do something else
pass
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = GUI(None, -1, "")
frame.Show(1)
app.MainLoop()
Если по какой-то причине вам нужен пустой StaticText, который вы связали с каждым RadioBox, тогда я бы просто сделал эту пару богатым компостированным виджетами с некоторыми методами изменения метки и т.д. Затем используйте метод 2 для создания и обновления их. Если вам нужно изменить эти атрибуты виджетов за пределами обработчика событий после их создания, я думаю, что вам нужно поддерживать ссылки на них в какой-либо форме или форме, например, методе 1.
Вот рабочий пример
import wx
import wx.lib.newevent
class LblRadBox(wx.Panel):
"""
Simple example of a composite widget
Add methods as required to improve functionality...
"""
def __init__(self, parent, stLbl="", rbLbl="", choices=[]):
wx.Panel.__init__(self, parent)
self.stLbl = wx.StaticText(self, label=stLbl)
self.rbox = wx.RadioBox(self, label=rbLbl, choices=choices)
sizer = wx.BoxSizer()
sizer.Add(self.stLbl)
sizer.Add(self.rbox)
self.SetSizerAndFit(sizer)
def SetSTLabel(self, lbl):
self.stLbl.SetLabel(lbl)
def GetLabel(self):
return self.rbox.GetLabel()
def GetSelection(self, lbl):
return self.rbox.GetSelection()
class GUI(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(700, 400))
panelControl = wx.Panel(self, 1, style=wx.MAXIMIZE)
sizerControl = wx.GridBagSizer(hgap=4,vgap = 4)
lblTitle = wx.StaticText(panelControl, label="Pick Scores")
self.btnRoll = wx.Button(panelControl, label="Roll!")
sizerControl.Add(lblTitle, pos=(0,0),
flag=wx.ALIGN_CENTER|wx.TOP|wx.LEFT|wx.BOTTOM, border=5)
sizerControl.Add(self.btnRoll, pos=(0,1),
span=(1,5), flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)
rboxPick = ["Default", "Strength", "Dexterity", "Constitution",
"Intelligence", "Wisdom", "Charisma"
]
labels = ["One", "Two", "Three", "Four"]
#Create, layout and bind the RadioBoxes
for row, label in enumerate(labels):
rbox = LblRadBox(panelControl, rbLbl="Roll %s"%(label), choices=rboxPick)
#if u want to be able to access the rboxes outside of onRadioBox()
#then add references of them to a dictionary like in method 1..
sizerControl.Add(rbox, pos=(row+1, 1), span=(1,5),
flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=2)
panelControl.Bind(wx.EVT_RADIOBOX, self.onRadioBox)
sizerMain = wx.BoxSizer()
sizerMain.Add(sizerControl)
panelControl.SetSizerAndFit(sizerMain)
def onRadioBox(self, evt):
"""Event handler for RadioBox.."""
rbox = evt.GetEventObject()#Get a reference to the RadioBox
rboxLbl = rbox.GetLabel() #We can identify the RadioBox with its label
selection = rbox.GetSelection()
print rboxLbl
print selection
if rboxLbl == "Roll One":
#do something
pass
elif rboxLbl == "Roll Two":
#do something else
pass
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = GUI(None, -1, "")
frame.Show(1)
app.MainLoop()
Они будут уникальными в любом случае, если вы не предоставите id
, который вы можете создать с помощью wx.NewId()
wx создаст его для вас.
Если вы позаботились о создании (или извлечении) идентификаторов и сохранили их (в списке, в dict, вы выбираете), то вы сможете вернуться ко всему отдельному элементу, чтобы его отредактировать.
ids = []
for lbl in ('Name', 'Surname', 'Address'):
st = wx.StaticText(panel)
tc = wx.TextControl(panel, label=lbl)
ids.append(tc.GetId())
В любом случае вы должны иметь возможность делать свои изменения, которые обычно отвечают на действия пользователя, только используя данные событий без необходимости хранить какой-либо идентификатор.