2015-10-26 2 views
-1

Я создал графический интерфейс с использованием wxFormBuilder и хочу динамически добавлять кнопки в sizer в GUI. Вот код wxFormBuilder.Доступ к определенному sizer из wxFormBuilder в Python

# -*- coding: utf-8 -*- 

########################################################################### 
## Python code generated with wxFormBuilder (version Jun 17 2015) 
## http://www.wxformbuilder.org/ 
## 
## PLEASE DO "NOT" EDIT THIS FILE! 
########################################################################### 

import wx 
import wx.xrc 

########################################################################### 
## Class HighVoltage 
########################################################################### 

class HighVoltage (wx.Frame): 

    def __init__(self, parent): 
     wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(1031,530), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL) 

     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 
     self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_ACTIVECAPTION)) 

     bSizer84 = wx.BoxSizer(wx.VERTICAL) 

     self.m_panel70 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer85 = wx.BoxSizer(wx.HORIZONTAL) 

     self.m_staticText79 = wx.StaticText(self.m_panel70, wx.ID_ANY, u"HV Documentation", wx.DefaultPosition, wx.DefaultSize, 0) 
     self.m_staticText79.Wrap(-1) 
     self.m_staticText79.SetFont(wx.Font(20, 70, 90, 92, False, "Century Gothic")) 

     bSizer85.Add(self.m_staticText79, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) 


     bSizer85.AddSpacer((0, 0), 1, wx.EXPAND, 5) 

     self.m_bitmap24 = wx.StaticBitmap(self.m_panel70, wx.ID_ANY, wx.Bitmap(u"LOGOtransSmall.png", wx.BITMAP_TYPE_ANY), wx.DefaultPosition, wx.DefaultSize, 0) 
     bSizer85.Add(self.m_bitmap24, 0, wx.ALL, 5) 


     self.m_panel70.SetSizer(bSizer85) 
     self.m_panel70.Layout() 
     bSizer85.Fit(self.m_panel70) 
     bSizer84.Add(self.m_panel70, 0, wx.EXPAND |wx.ALL, 5) 

     self.m_panel71 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer86 = wx.BoxSizer(wx.VERTICAL) 


     bSizer86.AddSpacer((0, 0), 1, wx.EXPAND, 5) 

     self.m_panel73 = wx.Panel(self.m_panel71, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer86.Add(self.m_panel73, 0, wx.EXPAND |wx.ALL, 5) 


     self.m_panel71.SetSizer(bSizer86) 
     self.m_panel71.Layout() 
     bSizer86.Fit(self.m_panel71) 
     bSizer84.Add(self.m_panel71, 1, wx.EXPAND |wx.ALL, 5) 

     self.m_panel72 = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL) 
     bSizer87 = wx.BoxSizer(wx.HORIZONTAL) 


     bSizer87.AddSpacer((0, 0), 1, wx.EXPAND, 5) 

     self.m_button65 = wx.Button(self.m_panel72, wx.ID_ANY, u"Exit", wx.DefaultPosition, wx.DefaultSize, 0) 
     bSizer87.Add(self.m_button65, 0, wx.ALL, 5) 


     self.m_panel72.SetSizer(bSizer87) 
     self.m_panel72.Layout() 
     bSizer87.Fit(self.m_panel72) 
     bSizer84.Add(self.m_panel72, 0, wx.EXPAND |wx.ALL, 5) 


     self.SetSizer(bSizer84) 
     self.Layout() 

     self.Centre(wx.BOTH) 

    def __del__(self): 
     pass 

Я хочу добавить кнопки в bSizer86, который является дочерним элементом m_panel71. Вот что я пробовал до сих пор.

class HvDocs(HighVoltage): 
    def __init__(self, parent): 
     HighVoltage.__init__(self, parent) 
     con = sqlite3.connect('hsmanagement.sqlite') 
     cur = con.execute('SELECT employee FROM employees WHERE hv=1 ORDER BY employee') 
     result = cur.fetchall() 
     con.close() 
     print result 
     sizer = self.GetSizer() 
     print type(sizer) 
     for f in range(0, len(result)): 
      sizer.Add(wx.Button(self, label=str(result[f][0]), id=int(f), size=(200, 40)), 2, wx.CENTER) 

Я попробовал несколько вариантов sizer = self.GetSizer(), таких как sizer = self.m_panel71 и sizer = self.GetSizer(self.m_panel71), но все, что я могу управлять, чтобы добавить кнопки на верхнем уровне классификаторе bSizer84. Как получить доступ к bSizer86?

+2

Еще один хороший ответ пришел, кроме вашего, через день после публикации этого вопроса - вы бы проголосовали, ответили или приняли его? – halfer

ответ

2

См. Следующий минимальный пример, как найти панели, кнопки и sizers только по названию. wxFormBuilder предлагает возможность установить wx.Window свойство window_name для элементов GUI, которые вы хотите отслеживать. Вы должны иметь возможность находить элемент управления, которому нужно знать это имя с помощью parent.FindWindowByName(…), не полагаясь на атрибут класса.

import wx 

TOK_PNL = 'window_name pnl' 
TOK_BTN = 'window_name btn' 

def on_btn(evt, parent): 
    btn = parent.FindWindowByName(TOK_BTN) 
    pnl = parent.FindWindowByName(TOK_PNL) 

    newbtn = wx.Button(pnl, -1, 'newbtn') 

    szsub = btn.GetContainingSizer() 
    szsub.Add(newbtn, 1, wx.EXPAND|wx.ALL, 4) 

    pnl.Layout() 


class testfrm(wx.Frame): 
    def __init__(self, *args, **kwds): 
     wx.Frame.__init__(self, *args, **kwds) 
     pnl = wx.Panel(self, -1) 
     pnl.SetName(TOK_PNL) 

     btn = wx.Button(pnl, -1, 'Add Button') 
     btn.SetName(TOK_BTN) 
     szmain = wx.BoxSizer(wx.VERTICAL) 
     szsub = wx.BoxSizer(wx.HORIZONTAL) 
     szsub.Add(btn, 0, wx.EXPAND|wx.ALL, 4) 
     szmain.Add(szsub) 

     pnl.SetSizer(szmain) 

     the_parent = self 
     btn.Bind(wx.EVT_BUTTON, lambda evt: on_btn(evt, the_parent)) 


if __name__ == '__main__': 
    app = wx.App(redirect=False) 
    frm = testfrm(None, -1, 'testfrm') 
    frm.Show() 
    app.MainLoop() 
0

Порывшись немного дальше и играть вокруг, я, наконец, решить мою проблему с помощью следующего кода

sizer = self.m_button67.GetContainingSizer() 
    self.m_button67.Destroy() 
    self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= "Ladder ID") 
    sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= "Engineer") 
    sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= "Description") 
    sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= "Last Check") 
    sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= "Next Check") 
    sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    for f in range(0, len(ladder_data)): 
     self.m_button = wx.Button(self.m_panel74, id=int(f), label=str(ladder_data[f][0])) 
     self.Bind(wx.EVT_BUTTON, self.detect_on_button) 
     sizer.Add(self.m_button, 0, wx.ALL, 5) 
     self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1])) 
     sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
     self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][2])) 
     sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
     self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][3])) 
     sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
     self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][4])) 
     sizer.Add(self.m_staticText, 0, wx.ALL, 5) 
    self.m_panel74.SetSizer(sizer) 
    self.m_panel74.Layout() 
    sizer.Fit(self.m_panel74) 

Ключ действительно было открытие GetContainingSizer(). Используя это с помощью кнопки фиктивной, созданной в wxFormBuilder (self.m_button67)

sizer = self.m_button67.GetContainingSizer() 

получает вас Sizer удалить кнопку манекена с

self.m_button67.Destroy() 

добавить вам виджеты с

self.m_staticText = wx.StaticText(self.m_panel74, wx.ID_ANY, label= str(ladder_data[f][1])) 
sizer.Add(self.m_staticText, 0, wx.ALL, 5) 

и макет завершен с

self.m_panel74.SetSizer(sizer) 
self.m_panel74.Layout() 
sizer.Fit(self.m_panel74) 

Надеюсь, что это поможет любому, у кого есть такая же проблема.