【问题标题】:wxPython: access sizer of GUI generated by wxFormBuilder and replace childwxPython:访问由 wxFormBuilder 生成的 GUI 的 sizer 并替换 child
【发布时间】:2015-05-15 07:41:53
【问题描述】:

我想在 MVC 的理念下构建我的应用程序,具有独立的 GUI 和控制器。另外,我有个同事在图形任务上比我好很多,我们想分配工作:他用 wxFormBuilder 构建图形部分,我构建应用程序的“机器”。

当我生成 GUI 时,我想替换一些 wxFormbuilder 无法管理的元素:例如 wxObjectListView。我的想法是用普通的 wxListBox 创建一个 GUI,用主程序导入它,然后用 wxObjectListView 替换它。我不想直接修改 wxFormBuilder 生成的代码,因为我想保持与 GUI 编辑器的向后兼容性。

问题和问题是:从导入GUI的主程序中,我如何访问包含列表的sizer,删除并由ObjectListView替换?像sizer.Delete(list) 然后sizer.Add(olv)...

这是一个例子:

wxFormBuilder生成的GUI代码:一个带有列表和按钮的Frame。

# -*- 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 必须有另一个结构,但我不知道如何制作它。我试过做了两级sizer,最终结果是一样的:我可以访问最终的元素,而不是sizer。

【问题讨论】:

  • 是的!有用。我做到了:sizer = wx.Window.GetSizer(self)sizer = self.GetSizer() 也可以。

标签: user-interface wxpython wxformbuilder objectlistview-python


【解决方案1】:

您需要将fgSizer 更改为self.fgSizer,以便稍后访问。然后你可以使用sizer的Remove方法来移除widget。有一个 Insert 方法,您可以使用它在其位置插入另一个小部件。

完整的详细信息,请参阅有关 sizer 的文档:

因为您要删除和插入一个小部件,所以您很可能需要在该方法结束时调用 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

现在在您的事件处理程序中,您可以使用这个字典来确定哪个小部件在哪个索引中:

index = self.widget_dict[some_widget]

【讨论】:

  • 我有,谢谢。我现在可以Replace,但是这样新的小部件不会继承被替换的比例和标志。 PrependAdd 以及稍后销毁旧的小部件工作正常,以防它是第一个或最后一个,并接受所有必要的参数。我也会尝试Insert,但现在的问题是获取旧小部件的索引。
  • 您可以将小部件的索引保存到字典或列表中,并使用它来帮助您解决问题。
  • 迈克:我不知道怎么做。这个问题让我意识到我对 wx 结构树和尺寸器、窗口和小部件概念(以及谁-包含-谁)的了解很薄弱。
  • 我在答案的末尾添加了一个简单的示例,可能会帮助您解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 2015-10-25
  • 1970-01-01
相关资源
最近更新 更多