zoukankan      html  css  js  c++  java
  • GridCellChoiceEditor

        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
    ' % 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
    ' % 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)
    ' % (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)
    ' % (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()
  • 相关阅读:
    oracle 误删除表的几种恢复方法
    解决js在alert或者断点调试时才能赋值
    常用的Debug方式
    字节对齐
    CWnd::SetWindowPos的注意事项
    网络模块代码调试要点
    stub和mock
    全局变量的缺陷
    SVN切换地址
    C/C++如何得到int型最大值
  • 原文地址:https://www.cnblogs.com/whwywzhj/p/6464119.html
Copyright © 2011-2022 走看看