0

Я хочу создать мои приложения под идеей MVC с отдельным графическим интерфейсом и контроллером. Кроме того, у меня есть работающий намного лучше меня в графических задачах, и мы хотим распространять работу: он создает графическую часть с помощью wxFormBuilder, и я создаю «механизм» приложения.wxPython: доступ к sizer графического интерфейса пользователя, созданного wxFormBuilder, и заменить его.

Когда у меня есть сгенерированный графический интерфейс, я хочу заменить некоторые элементы, которые не может управлять wxFormbuilder: например, wxObjectListView. Моя идея - создать графический интерфейс с обычным wxListBox, импортировать его с основной программой и заменить его на wxObjectListView. Я не хочу напрямую изменять сгенерированный код с помощью wxFormBuilder, потому что я хочу поддерживать обратную совместимость с графическим редактором.

Проблема и вопрос: из основной программы, которая импортирует GUI, как я могу получить доступ к sizer, который содержит список, удалить и заменить ObjectListView? Что-то вроде sizer.Delete (список), а затем sizer.Add (OLV) ...

Здесь вы пример:

ГИП код, сгенерированный wxFormBuilder: Кадр со списком и кнопки.

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

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

import wx 

########################################################################### 
## Class MyFrame1 
########################################################################### 

class MyFrame1 (wx.Frame): 

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

     self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize) 

     fgSizer = wx.FlexGridSizer(2, 1, 0, 0) 
     fgSizer.AddGrowableCol(0) 
     fgSizer.AddGrowableRow(0) 
     fgSizer.SetFlexibleDirection(wx.BOTH) 
     fgSizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED) 

     m_listBox1Choices = [ u"Row1", u"Row2" ] 
     self.m_listBox1 = wx.ListBox(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_listBox1Choices, 0) 
     fgSizer.Add(self.m_listBox1, 1, wx.ALL|wx.EXPAND, 5) 

     self.m_button1 = wx.Button(self, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0) 
     fgSizer.Add(self.m_button1, 1, wx.ALL|wx.EXPAND, 5) 

     self.SetSizer(fgSizer) 
     self.Layout() 

     self.Centre(wx.BOTH) 

    def __del__(self): 
     pass 

И вот основной код, который импортирует графический класс.

from __future__ import print_function 
# -*- coding: utf-8 -*- 
import wx 
from olvGUI import MyFrame1 

class Ventana(MyFrame1): 

    def inicia(self): 
     hijos = self.GetChildren() 
     for h in hijos: 
      print(h) 


if __name__ == "__main__": 
    app = wx.App(False) 
    v = Ventana(None) 
    v.inicia() 
    v.Show() 
    app.MainLoop() 

Когда я пытаюсь получить доступ к детям Frame, я вижу только «конечные» объекты, а не Sizer.

<wx._controls.ListBox; proxy of <Swig Object of type 'wxListBox *' at 0x1e0cea8> > 
<wx._controls.Button; proxy of <Swig Object of type 'wxButton *' at 0x19a5f90> > 

Может быть, GUI должен иметь другую структуру, если я хочу сделать это его элементы accesibles, но я понятия не имею, как это сделать. Я попытался сделать два уровня sizers, и конечный результат будет таким же: я могу получить доступ к конечным элементам, а не к sizers.

+1

wx.Window.GetSizer? –

+0

Да! Оно работает. Я сделал: 'sizer = wx.Window.GetSizer (self)' и 'sizer = self.GetSizer()' работает тоже. – neogurb

ответ

1

Вам необходимо будет изменить fgSizer на номер self.fgSizer, чтобы вы могли получить к нему доступ позже. Затем вы можете использовать метод ssizer для удаления виджета. Существует метод Insert, который можно использовать для вставки другого виджета в его место.

Смотрите документацию по дробилок для получения полной информации:

Потому что вы удаление и вставка виджета, вы, скорее всего, нужно вызвать Layout в конце этого метода.В этой статье есть пример:

Наконец, вот пример получения Sizer:

import wx 

######################################################################## 
class MyFrame(wx.Frame): 
    """""" 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     """Constructor""" 
     wx.Frame.__init__(self, None, title='Test') 
     self.panel = wx.Panel(self) 

     sizer = wx.BoxSizer(wx.VERTICAL) 

     btn = wx.Button(self.panel, label="Get sizer") 
     btn.Bind(wx.EVT_BUTTON, self.onGetSizer) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     self.panel.SetSizer(sizer) 

     self.Show() 

    #---------------------------------------------------------------------- 
    def onGetSizer(self, event): 
     """""" 
     sizer = self.panel.GetSizer() 

if __name__ == '__main__': 
    app = wx.App(False) 
    frame = MyFrame() 
    app.MainLoop() 

Ниже приведен пример сохранения индекса вашего виджета:

self.widget_dict = {} 
some_boxsizer.Add(some_widget) # this is the first widget, so its ID is zero 
self.widget_dict[some_widget] = 0 

Теперь в вашем обработчике событий вы можете использовать этот dicti чтобы определить, что такое виджет, в каком индексе:

index = self.widget_dict[some_widget] 
+0

У меня оно есть, спасибо. Теперь я могу «Заменить», но таким образом новый виджет не наследует пропорции и флаги замененных. 'Prepend' или' Add', а затем уничтожить старый виджет отлично работает, если он был первым или последним и принимает все необходимые параметры. Я также попробую «Вставить», но теперь проблема заключается в получении индекса старого виджета. – neogurb

+0

Вы можете сохранить индекс виджетов в словаре или списке и использовать это, чтобы помочь вам разобраться. –

+0

Майк: У меня нет идеи, как это сделать. Эта проблема заставляет меня понять, что мои знания о структуре дерева wx и sizers, видах и виджетах (и кто-содержит-кто) слабый. – neogurb