我有一个名为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,但是它有些错误/实际上没有做我需要的事情。)
答案 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”,但这是辩论。另外,如果没有一些聪明的技巧,你最后会留下一个列表,这可能不适合你。
关于您的解决方案的一些注意事项:
if
语句更改为if...elif...(else)
构造,但在这种情况下它实际上并不是那么大,因为您不希望任何小部件进行多个测试希望这有帮助