在wxPython中访问FlexGridSizer中项目的正确方法?

时间:2014-03-03 17:01:36

标签: python wxpython

我有一个名为self.grid的FlexGridSizer,有五列,每行有两个TextCtrl,一对RadioButton和一个CheckBox。检索与这些对象关联的数据的最佳方法是什么?目前我成功使用

# get flat list of all items in flexgridsizer, self.grid
children = list(self.grid.GetChildren())

# change list into list of rows (5 items each)
table = [children[i:i+5] for i in range(0, len(children), 5)]

# parse list of 'sizeritems' to extract content
for x in range(len(table)):
    for y in range(len(table[x])):
        widget = table[x][y].GetWindow()
        if isinstance(widget, wx.TextCtrl):
            text = ""
            for num in range(widget.GetNumberOfLines()):
                text += widget.GetLineText(num)
            table[x][y] = text
        if isinstance(widget, wx.RadioButton):
            table[x][y] = widget.GetValue()
        if isinstance(widget, wx.CheckBox):
            table[x][y] = (widget.GetLabel(), widget.GetValue())

这给我留下了table,一个行列表,每行包含五个元素,每个项目都是相关数据:TextCtrl的文本,RadioButton的bool和CheckBox的(label,bool)。 这似乎完成了工作,但它并没有感觉正确。

有没有更好的方法从FlexGridSizer恢复数据?或者,我应该为此布局使用不同的sizer / control吗? (我尝试过UltimateListCtrl,但是它有些错误/实际上没有做我需要的事情。)

2 个答案:

答案 0 :(得分:0)

你不应该这样做......相反,你应该在创建时创建对它们的引用

self.widgetTable = []
for row in dataSet:
   self.widgetTable.append([wx.TextCtrl(self,-1,value) for value in row])

然后通过

访问它们
self.widgetTable[0][0].GetValue()

答案 1 :(得分:0)

由于您有工作代码,并且似乎在询问编码风格,因此您可能会对Code Review提出异议。

话虽如此,你在这里所拥有的并不是太可怕。我认为isinstance()非常丑陋,所以当我做这样的事情的时候,我按照小部件的顺序去了,因为我知道每个第五个小部件都是我想要的。也许你可以使用类似的方法?或使用try...except结构来避免isinstance

所以这里有两种方法,第一种方法基于小部件的顺序,第二种方法只是猜测你如何检索信息。

方法1:因此,如果您的小部件有正常的顺序,您可以执行以下操作:(仅用于演示的可怕变量名称)

list_of_one_type_of_widget = map(lambda x: x.GetWindow(), self.grid.GetChildren())[::k]
list_of_values_for_first_type = map(lambda x: x.GetValue(), list_of_one_type_of_widget)

list_of_another_type_of_widget = map(lambda x: x.GetWindow(), self.grid.GetChildren())[1::k]
list_of_values_for_first_type = map(lambda x: (x.GetLabel(), x.GetValue()), list_of_another_type_of_widget)

其中k是您拥有的窗口小部件类型的数量。当我遇到这个问题时,这就是我解决这个问题的方法,我认为它非常漂亮而且非常简洁。您将获得每种类型的小部件列表,因此,如果它取决于小部件,则可以轻松处理。您也可以很容易地将其重新构建到表中。请务必注意第二个如何使用[1::k]而不是[::k]进行切片。每个后续窗口小部件类型都需要比前一个更大。

方法2:如果您没有常规订单,可以执行以下操作:

list_of_values = []
for widget in map(lambda x: x.GetWindow(), self.grid.GetChildren()):
    try:
        list_of_values.append(widget.GetValue())
    except:
        #Same as above, but with the appropriate Get function.  If there multiple alternatives, just keep nesting try...except blocks in decrease order of commonness

你可以说第二种方法更“pythonic”,但这是辩论。另外,如果没有一些聪明的技巧,你最后会留下一个列表,这可能不适合你。

关于您的解决方案的一些注意事项:

  • self.grid.GetChildren()是可迭代的,因此在将其用作可迭代之前,您无需将其转换为列表
  • 您可以将序列if语句更改为if...elif...(else)构造,但在这种情况下它实际上并不是那么大,因为您不希望任何小部件进行多个测试

希望这有帮助