Wxpython 帮助引用wxDesigner面板克隆副本中的小部件

Wxpython 帮助引用wxDesigner面板克隆副本中的小部件,wxpython,Wxpython,我对wx.python编程相当陌生,在实现我的目标方面遇到了困难。我正在设计一个程序,检查目录中的特定文件特征,并将有关目录和文件的信息返回给用户。然后,用户将对每个目录进行选择。这些选择被传递回控制程序。 因为为每个x目录提供给用户的信息格式是相同的,所以我在wxDesigner中创建了面板来显示这些信息并与之交互。这些面板在滚动面板中插入x次。(我相信wxDesigner实际上返回了一个父大小器,它插入到滚动面板中的主大小器中。)到目前为止还不错 当我尝试访问出现的不同表单时,我的麻烦就开始

我对wx.python编程相当陌生,在实现我的目标方面遇到了困难。我正在设计一个程序,检查目录中的特定文件特征,并将有关目录和文件的信息返回给用户。然后,用户将对每个目录进行选择。这些选择被传递回控制程序。 因为为每个x目录提供给用户的信息格式是相同的,所以我在wxDesigner中创建了面板来显示这些信息并与之交互。这些面板在滚动面板中插入x次。(我相信wxDesigner实际上返回了一个父大小器,它插入到滚动面板中的主大小器中。)到目前为止还不错

当我尝试访问出现的不同表单时,我的麻烦就开始了。因为我要插入在wxDesigner中创建的表单,所以ID被分配一次并应用于表单的所有副本。因为我要插入整个表单的副本,所以我无法为每个重复字段创建单独的ID,正如我在运行时创建并插入到面板中的多个小部件的许多示例(在我搜索网络的许多小时中)中所看到的那样

我在一个迭代循环中添加表单。我尝试给插入表单的实例分别命名,我使用SetId()、NewId()等重新分配了ID,但运气不好。我也尝试过使用SetName(),但在这两种方法中,我总是在最后插入的表单上指定ID或名称,引用所有表单上所有匹配的小部件

我遇到了许多死角,下一步考虑在插入wxDesigner对象时创建单独的面板。但只有当我能够通过parent.widget引用一个小部件时,这才有效,而且我还没有看到任何这样做的例子。我还考虑在wxDesigner xxx_wdr.py文件中编写一个procedure(一旦我知道它不会更改),为每个插入的实例生成单独的ID。但在我把头撞到墙上之前,我想我应该寻求帮助,知道该往哪个方向走


如果只是一个小细节的问题,我可以展示我的代码(多次尝试的一个版本),但让我们从在这种情况下所采用的一般方法的建议开始。任何帮助都将不胜感激。谢谢,

我不熟悉wxDesigner,但是如果您有同一个wx.Panel(或任何东西)的多个相同副本,最好在将它们添加到主窗体时将它们添加到
列表或
dict
。这将允许您单独访问它们以及它们的任何子项(通过您提到的parent.widget)。您还可以使用访问器函数将面板包装在自己的类中,以从类外部检索值,而无需直接调用小部件

伪代码:

class CustomPanel:
    def __init__(self, parent, etc):
        GeneratedPanel.__init__(self, parent, etc)

    def GetFirstThing(self):
        return self.FirstThing.GetValue()

    def GetSecondThing(self):
        return self.SecondThing.GetValue()

class MainWindow:
    def __init__(self, parent, etc)
        #...
        self.panels = []
        for i in range(10):
            self.panels.append(CustomPanel(self, etc))

    def GetSomeValue(self, index):
        return self.panels[index].GetFirstThing()

您应该能够用wx.id\u ANY替换代码的id行。此外,您可以在实例化小部件时设置其名称。下面是一个例子:

btn=wx.按钮(父项,name=“myBtn”)

如果需要从父窗口小部件获取子窗口小部件,则必须执行以下操作:

children = parent.GetChildren()

for child in children:
   if child.GetName() == "someName":  # or child.GetId() or whatever
      # do something here

我不知道这对你是否有帮助。

谢谢你的建议,绝对是有用的信息!我不能使用类面板方法,因为我不能编辑wxPython生成的代码,但是看看它是如何完成的很有用

我的解决方案是通过SetId()将代码中的静态Id重新分配给一个数字,该数字由特定小部件的固定Id加上插入表单的迭代次数t组成。这为每个小部件/表单创建了一个唯一的id。我使用字典(谢谢,Mike)来查找id的基本部分,并且可以在任何时候附加迭代计数来引用它们。我使用了一个过程来简化查找小部件id的过程,因此我不需要重复键入'FindWindow….'位。可能还有更优雅的方式,但这是可行的:

        widgetId = {
        'btn' : 6000,
        'textctrl' : 6010,
        'textlbl' :6020 }

    def getWidget(self, widget, formNo ):
        '''Finds widget window via lookup of re-assigned widget ID #'s'''
        widget = self.FindWindowById(self.widgetId[widget] + formNo)
        return widget

    def cloneWX(self):
        '''Reassign ID at time of cloning'''
        for  formNo in range(self.clones):
            # Insert the cloned form (a BoxSizer created by wxDesigner) into this copy:
            self.form = NewDialog( self.panel1, True, set_sizer = False)
            self.grid.Add(self.form, flag=wx.RIGHT, border=10)

            # Set initial references:
            self.textlbl = self.FindWindowById( ID_TEXT )
            self.textctrl = self.FindWindowById( ID_TEXTCTRL)
            self.btn = self.FindWindowById( ID_BUTTON_1 )

            # Reset ID based on form number: (Can reference via dictionary instead))
            self.btn.SetId(6000 + formNo)
            self.textctrl.SetId(6010 + formNo)
            self.textlbl.SetId(6020 + formNo)

            # Bind events to new ID references:
            wx.EVT_BUTTON(self, 6000 + formNo, self.OnBtn)

    def OnBtn(self, event):
        event_object = event.GetEventObject()
        # From the event id, extract the form number where this widget appears :
        formNo = event_object.GetId() - self.widgetId['btn']

        textctrl = self.getWidget('textctrl', formNo)
        textlbl = self.getWidget('textlbl', formNo)
        textlbl.SetLabel(textctrl.GetValue())