choice_editor = wx.grid.GridCellChoiceEditor(choices_list, True)
grid.SetCellEditor(row, col, choice_editor)

Dynamic list updating with a GridCellChoiceEditor

A common question is how to dynamically update the list in a GridCellChoiceEditor. The problem comes from not having direct access to the underlying ComboBox widget in the grid editor. Fortunately the grid editor throws an event that allows us to get to the underlying ComboBox.

In addition to dynamic updates to the choice list, having access to the underlying ComboBox allows us to use application data and the choice index.

The following example shows a method of doing this.

切换行号显示

1 #-----------------------------------------------------------------------------
2 # Name: GridCombo.py
3 # Purpose: Dynamic list updating with a wx.grid.GridCellChoiceEditor
4 #
5 # Author: Thomas M Wetherbee
6 #
7 # Created: 2009/04/27
8 # RCS-ID: $Id: GridCombo.py $
9 # Copyright: (c) 2009
10 # Licence: Distributed under the terms of the GNU General Public License
11 #-----------------------------------------------------------------------------
12 #!/usr/bin/env python
13
14
15 '''
16 Dynamic list updating with a wx.grid.GridCellChoiceEditor.
17
18 This example shows how to dynamically update the choices in a
19 GridCellChoiceEditor. This simple example creates a two column
20 grid where the top row in each column is a wx.grid.GridCellChoiceEditor.
21 The choices listed in the editor are created on the fly, and may change
22 with each selection. Text entered into the GridCellChoiceEditor cell
23 is appended as an additional choice.
24
25 In addition to appending new choices, this example also shows how to get
26 the selection index and client data from the choice.
27
28 Cell editor interactions are printed for every step.
29
30 This example is deliberately simple, lacking sizers and other useful but
31 confusing niceties.
32
33 Theory:
34
35 The GridCellChoiceEditor uses an underlying ComboBox to do the editing.
36 This underlying ComboBox is created when the cell editor is created. Normally
37 the ComboBox is completely hidden, but in this example we retrieve a reference
38 to the ComboBox and use it to load choices and retrieve index and client data.
39
40 The example starts with a GridCellChoiceEditor attached to the two top cells of
41 the grid. When the GridCellChoiceEditor is invoked for the first time, two
42 choice items are added to the choice list along with their associated user
43 data. The items are ('spam', 42) and ('eggs', 69), where spam is the text to
44 display and 42 is the associated client data. In this example 'spam' has an
45 index of 0 while eggs, being the second item of the list, has an index of 1.
46
47 Note that the index and user data are not required. The demonstrated method
48 works fine without either, but sometimes it is useful to know the index of a
49 selection, especially when the user is allowed to create choices. For example,
50 we might have the list ['spam', 'eggs', 'spam', 'spam'] where the three spam
51 items are different objects. In this case simply returning the item value
52 'spam' is ambiguous. We need to know the index, or perhaps some associated
53 client data.
54
55 In our example, when the user enters a new choice, the choice is appended to
56 the end of the choice list. A unique integer number is created for each new
57 choice, in succession, with the first number being 100. This number is used
58 for client data.
59
60 In this example we bind directly to the ComboBox events, rather than getting
61 the events through the frame. This is done to keep the grid from eating the
62 events. The difference in binding can be seen in the two binding methods:
63
64 self.Bind(wx.EVT_BUTTON, self.OnButton, self.button)
65 self.button.Bind(wx.EVT_BUTTON, self.OnButton)
66
67 The latter method binds directly to the widget, where the first method
68 receives the event up the chain through the parent.
69
70 Note that this example does not save the new choice list: it persists only
71 for the life of the program. In a real application, you will probably want
72 to save this list and reload it the next time the program runs.
73 '''
74
75 import wx
76 import wx.grid
77
78 ##modules ={}
79
80 class Frame1(wx.Frame):
81 def __init__(self, parent):
82 wx.Frame.__init__(self, id=-1, name='', parent=None,
83 pos=wx.Point(100, 100), size=wx.Size(480, 250),
84 style=wx.DEFAULT_FRAME_STYLE, title='Spam & Eggs')
85 self.SetClientSize(wx.Size(400, 250))
86
87 self.scrolledWindow1 = wx.ScrolledWindow(id=-1,
88 name='scrolledWindow1', parent=self, pos=wx.Point(0, 0),
89 size=wx.Size(400, 250), style=wx.HSCROLL | wx.VSCROLL)
90
91 self.grid1 = wx.grid.Grid(id=-1, name='grid1',
92 parent=self.scrolledWindow1, pos=wx.Point(0, 0),
93 size=wx.Size(400, 250), style=0)
94
95 self.grid1.CreateGrid(4, 2)
96
97 #Create the GridCellChoiceEditor with a blank list. Items will
98 #be added later at runtime. "allowOthers" allows the user to
99 #create new selection items on the fly.
100 tChoiceEditor = wx.grid.GridCellChoiceEditor([], allowOthers=True)
101
102 #Assign the cell editors for the top row (row 0). Note that on a
103 #larger grid you would loop through the cells or set a default.
104 self.grid1.SetCellEditor(0, 0, tChoiceEditor)
105 self.grid1.SetCellEditor(0, 1, tChoiceEditor)
106
107 #Create a starter list to seed the choices. In this list the item
108 #format is (item, ClientData), where item is the string to display
109 #in the drop list, and ClientData is a behind-the-scenes piece of
110 #data to associate with this item. A seed list is optional.
111 #If this were a real application, you would probably load this list
112 #from a file.
113 self.grid1.list = [('spam', 42), ('eggs', 69)]
114
115 #Show the first item of the list in each ChoiceEditor cell. The
116 #displayed text is optional. You could leave these cells blank, or
117 #display 'Select...' or something of that nature.
118 self.grid1.SetCellValue(0, 0, self.grid1.list[0][0])
119 self.grid1.SetCellValue(0, 1, self.grid1.list[0][0])
120
121 #The counter below will be used to automatically generate a new
122 #piece of unique client data for each new item. This isn't very
123 #useful, but it does let us demonstrate client data. Typically
124 #you would use something meaningful for client data, such as a key
125 #or id number.
126 self.grid1.counter = 100
127
128 #The following two objects store the client data and item index
129 #from a choice selection. Client data and selection index are not
130 #directly exposed to the grid object. We will get this information by
131 #directly accessing the underlying ComboBox object created by the
132 #GridCellChoiceEditor.
133 self.grid1.data = None
134 self.grid1.index = None
135
136
137 self.grid1.Bind(wx.grid.EVT_GRID_CELL_CHANGE,
138 self.OnGrid1GridCellChange)
139
140 self.grid1.Bind(wx.grid.EVT_GRID_EDITOR_CREATED,
141 self.OnGrid1GridEditorCreated)
142
143 self.grid1.Bind(wx.grid.EVT_GRID_EDITOR_HIDDEN,
144 self.OnGrid1GridEditorHidden)
145
146
147 #This method fires when a grid cell changes. We are simply showing
148 #what has changed and any associated index and client data. Typically
149 #this method is where you would put your real code for processing grid
150 #cell changes.
151 def OnGrid1GridCellChange(self, event):
152 Row = event.GetRow()
153 Col = event.GetCol()
154
155 #All cells have a value, regardless of the editor.
156 print 'Changed cell: (%u, %u)' % (Row, Col)
157 print 'value: %s' % self.grid1.GetCellValue(Row, Col)
158
159 #Row 0 means a GridCellChoiceEditor, so we should have associated
160 #an index and client data.
161 if Row == 0:
162 print 'index: %u' % self.grid1.index
163 print 'data: %s' % self.grid1.data
164
165 print '' #blank line to make it pretty.
166 event.Skip()
167
168
169 #This method fires when the underlying GridCellChoiceEditor ComboBox
170 #is done with a selection.
171 def OnGrid1ComboBox(self, event):
172 #Save the index and client data for later use.
173 self.grid1.index = self.comboBox.GetSelection()
174 self.grid1.data = self.comboBox.GetClientData(self.grid1.index)
175
176 print 'ComboBoxChanged: %s' % self.comboBox.GetValue()
177 print 'ComboBox index: %u' % self.grid1.index
178 print 'ComboBox data: %u\n' % self.grid1.data
179 event.Skip()
180
181
182 #This method fires when any text editing is done inside the text portion
183 #of the ComboBox. This method will fire once for each new character, so
184 #the print statements will show the character by character changes.
185 def OnGrid1ComboBoxText(self, event):
186 #The index for text changes is always -1. This is how we can tell
187 #that new text has been entered, as opposed to a simple selection
188 #from the drop list. Note that the index will be set for each character,
189 #but it will be -1 every time, so the final result of text changes is
190 #always an index of -1. The value is whatever text that has been
191 #entered. At this point there is no client data. We will have to add
192 #that later, once all of the text has been entered.
193 self.grid1.index = self.comboBox.GetSelection()
194
195 print 'ComboBoxText: %s' % self.comboBox.GetValue()
196 print 'ComboBox index: %u\n' % self.grid1.index
197 event.Skip()
198
199
200 #This method fires after editing is finished for any cell. At this point
201 #we know that any added text is complete, if there is any.
202 def OnGrid1GridEditorHidden(self, event):
203 Row = event.GetRow()
204 Col = event.GetCol()
205
206 #If the following conditions are true, it means that new text has
207 #been entered in a GridCellChoiceEditor cell, in which case we want
208 #to append the new item to our selection list.
209 if Row == 0 and self.grid1.index == -1:
210 #Get the new text from the grid cell
211 item = self.comboBox.GetValue()
212
213 #The new item will be appended to the list, so its new index will
214 #be the same as the current length of the list (origin zero).
215 self.grid1.index = self.comboBox.GetCount()
216
217 #Generate some unique client data. Remember this counter example
218 #is silly, but it makes for a reasonable demonstration. Client
219 #data is optional. If you can use it, this is where you attach
220 #your real client data.
221 self.grid1.data = self.grid1.counter
222
223 #Append the new item to the selection list. Remember that this list
224 #is used by all cells with the same editor, so updating the list
225 #here updates it for every cell using this editor.
226 self.comboBox.Append(item, self.grid1.data)
227
228 #Update the silly client data counter
229 self.grid1.counter = self.grid1.counter + 1
230
231 print 'OnGrid1EditorHidden: (%u, %u)\n' % (Row, Col)
232
233 event.Skip()
234
235 #This method fires when a cell editor is created. It appears that this
236 #happens only on the first edit using that editor.
237 def OnGrid1GridEditorCreated(self, event):
238 Row = event.GetRow()
239 Col = event.GetCol()
240
241 print 'OnGrid1EditorCreated: (%u, %u)\n' % (Row, Col)
242
243 #In this example, all cells in row 0 are GridCellChoiceEditors,
244 #so we need to setup the selection list and bindings. We can't
245 #do this in advance, because the ComboBox control is created with
246 #the editor.
247 if Row == 0:
248 #Get a reference to the underlying ComboBox control.
249 self.comboBox = event.GetControl()
250
251 #Bind the ComboBox events.
252 self.comboBox.Bind(wx.EVT_COMBOBOX, self.OnGrid1ComboBox)
253 self.comboBox.Bind(wx.EVT_TEXT, self.OnGrid1ComboBoxText)
254
255 #Load the initial choice list.
256 for (item, data) in self.grid1.list:
257 self.comboBox.Append(item, data)
258
259 event.Skip()
260
261
262if __name__ == '__main__':
263 app = wx.PySimpleApp()
264 frame = Frame1(None)
265 frame.Show(True)
266 app.MainLoop()

GridCellChoiceEditor的更多相关文章

  1. python---基础知识回顾(九)图形用户界面-------WxPython

    主要使用wxPython(最成熟的跨平台python GUI工具包) wxPython手册 前戏:基础了解 import wx class MyFrame(wx.Frame): #创建自定义Frame ...

随机推荐

  1. Qt 学习之路 2(56):使用模型操作数据库

    Qt 学习之路 2(56):使用模型操作数据库 (okgogo: skip) 豆子 2013年6月20日 Qt 学习之路 2 13条评论 前一章我们使用 SQL 语句完成了对数据库的常规操作,包括简单 ...

  2. 16. js 判断变量类型,包括ES6 新类型Symbol

    相信大家在开发中遇到需要判断变量类型的问题,js变量按存储类型可分为值类型和引用类型,值类型包括Undefined.String.Number.Boolean,引用类型包括object.Array.F ...

  3. 斐讯 N1 刷 Armbian 5.75

    前言 不知不觉居然鸽了快半年的博客_(:3」∠)_ 好吧最近发现之前玩的 N1 Armbian 系统已经出到 5.75 了,之前刷 5.64 玩过,具体博文在此,说实话并不是很稳定,有线网络有时会卡死 ...

  4. Linux系统下Qt环境搭建

    http://www.linuxidc.com/Linux/2013-07/87576.htm 主要是需要提前安装一些动态库,否则编译的时候会出现 /usr/bin/ld: cannot find - ...

  5. vue的props和$emit / 父子组件通信

    props 父级: 父级组件中引用子组件,并将自己data下面的giveChild数据绑定在  giveChildData  传给子 <myChild :giveChildData=" ...

  6. Oracle9i之xmltype应用(2)

    Oracle 9i提供的XML内置特性: Oracle 9i支持XMLType类型,它是一种Oracle 9i系统定义的对象类型.XMLType有内置的函数,有力的提供了推XML的创建,索检,索引等功 ...

  7. Python基础 (上)

    参考:菜鸟教程    Python用途 目录 一.数据类型 二.运算符 三.条件和循环控制语句 四.函数 五.模块 六.输入与输出 一.数据类型 string.list和tuple都属于sequenc ...

  8. Linux中断分层--软中断和tasklet

    1. Linux中断分层 (1)上半部:当中断发生时,它进行相应的硬件读写,并“登记”该中断.通常由中断处理程序充当上半部.(一般情况下,上半部不可被打断) (2)下半部:在系统空闲的时候,对上半部“ ...

  9. 《The Python Standard Library》——http模块阅读笔记1

    官方文档:https://docs.python.org/3.5/library/http.html 偷个懒,截图如下: 即,http客户端编程一般用urllib.request库(主要用于“在这复杂 ...

  10. Go初探

      官方网站:https://golang.org/ 标准库文档:https://golang.org/pkg/ 在线编码学习:https://play.golang.org/ PS:请自行FQ 简介 ...