Introduction

This recipe is an adaptation of one of the wxPython demos currently available (as of 2004-05-12).

It shows how to arrange:

to redefine column names (and, presumably, other attributes of columns at run-time, and

to repopulate a list from an iterator, in this case a MySQL cursor Execute .

I have chopped out a lot of events machinery that was present in the original demo (merely to preserve my own sanity).

What Objects are Involved

wxListCtrl , wxListCtrlAutoWidthMixin , wxColumnSorterMixin

Process Overview

One can postpone columns definition until the list control is actually displayed. In this recipe column names are provided to the panel that hosts the list control as an attribute of the panel.

It appears to be safe to delete all of the items from a list even when the list is empty.

In this recipe the Execute method of a MySQL cursor is started to provide an iterator as a source of rows or records for populating the list using CreateRecords .

Finally PopulateList blends information about column names and from the iterator to make the list.

Special Concerns

Column names must be presented in the same order in which field values appear in rows from the iterator. Additional field values in iterator rows are ignored.

Code Sample

1 from wxPython.wx import * 2 from wxPython.lib.mixins.listctrl import wxColumnSorterMixin , wxListCtrlAutoWidthMixin 3 4 from DisplayRecordsImages import getWhiteSquareBitmap , getSmallUpArrowBitmap , getSmallDnArrowBitmap , getXOnWhBitmap 5 6 class DisplayRecordsCtrl ( wxListCtrl , wxListCtrlAutoWidthMixin ) : ) : 7 8 def __init__ ( self , parent , ID , pos = wxDefaultPosition , size = wxDefaultSize , style = 0 ) : ) : 9 10 wxListCtrl . __init__ ( self , parent , ID , pos , size = parent . GetClientSize ( ), style = style ) ( ), 11 wxListCtrlAutoWidthMixin . __init__ ( self ) 12 13 class DisplayRecordsCtrlPanel ( wxPanel , wxColumnSorterMixin ) : ) : 14 15 def __init__ ( self , parent , columnNames = [ ], size = ( - 1 , - 1 ) ) : = [ ],= ( -, -) ) : 16 17 wxPanel . __init__ ( self , parent , - 1 , size = size ) , - 18 19 listId = wxNewId ( ) ( ) 20 21 self . il = wxImageList ( 16 , 16 ) 22 self . idx1 = self . il . Add ( getWhiteSquareBitmap ( ) ) ( ) ) 23 self . sm_up = self . il . Add ( getSmallUpArrowBitmap ( ) ) ( ) ) 24 self . sm_dn = self . il . Add ( getSmallDnArrowBitmap ( ) ) ( ) ) 25 self . deleted = self . il . Add ( getXOnWhBitmap ( ) ) ( ) ) 26 27 self . list = DisplayRecordsCtrl ( self , listId , style = wxLC_REPORT | wxSUNKEN_BORDER ) 28 self . list . SetImageList ( self . il , wxIMAGE_LIST_SMALL ) 29 30 self . columnNames = columnNames 31 32 wxColumnSorterMixin . __init__ ( self , len ( columnNames ) ) ) ) 33 34 EVT_SIZE ( self , self . OnSize ) 35 EVT_LIST_ITEM_SELECTED ( self , listId , self . OnItemSelected ) 36 37 def CreateRecords ( self , recordsIterator ) : ) : 38 39 self . itemDataMap = { } = { } 40 for i , row in enumerate ( recordsIterator ) : self . itemDataMap [ i ] = tuple ( row [ : len ( self . columnNames ) ] ) ) :] =[ :) ] ) 41 42 def PopulateList ( self ) : ) : 43 44 info = wxListItem ( ) ( ) 45 info . m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT 46 info . m_image = - 1 = - 47 info . m_format = 0 48 49 while self . list . GetColumnCount ( ) : ( ) : 50 self . list . DeleteColumn ( 0 ) 51 52 for c , columnName in enumerate ( self . columnNames ) : ) : 53 info . m_text = columnName 54 self . list . InsertColumnInfo ( c , info ) 55 56 items = self . itemDataMap . items ( ) ( ) 57 for itemNumber , ( key , data ) in enumerate ( items ): , (): 58 self . list . InsertImageStringItem ( itemNumber , data [ 0 ], self . idx1 ) ], 59 for j in range ( 1 , len ( data ) ) : ) ) : 60 dataAsString = ' ' 61 if data [ j ] : ] : 62 dataAsString = str ( data [ j ] ) ] ) 63 self . list . SetStringItem ( itemNumber , j , dataAsString ) 64 self . list . SetItemData ( itemNumber , key ) 65 66 for c in range ( len ( self . columnNames ) ) : ) ) : 67 self . list . SetColumnWidth ( c , wxLIST_AUTOSIZE ) 68 69 self . currentItem = 0 70 71 def GetListCtrl ( self ) : ) : 72 73 return self . list 74 75 def GetSortImages ( self ) : ) : 76 77 return self . sm_dn , self . sm_up 78 79 def OnSize ( self , event ) : ) : 80 w , h = self . GetClientSizeTuple ( ) ( ) 81 self . list . SetDimensions ( 0 , 0 , w , h ) 82 83 def getColumnText ( self , index , col ): ): 84 item = self . list . GetItem ( index , col ) 85 return item . GetText ( ) ( ) 86 87 def OnItemSelected ( self , event ): ): 88 self . currentItem = event . m_itemIndex 89 event . Skip ( ) ( ) 90 91 if __name__ == " __main__ " : == 92 93 import adodb 94 95 db = adodb . NewADOConnection ( ' mysql ' ) 96 db . Connect ( ' ' , ' ' , ' ' , ' FWOTS ' ) 97 98 def AddMenuItem ( menu , label , parent , handler , helpText = ' ' ) : ) : 99 anId = wxNewId ( ) ( ) 100 menu . Append ( anId , label , helpText ) 101 EVT_MENU ( parent , anId , handler ) 102 return anId 103 104 class MainFrame ( wxFrame ) : ) : 105 106 def __init__ ( self , * args ) : , *) : 107 108 wxFrame . __init__ ( self , * args ) , * 109 110 self . CreateStatusBar ( ) ( ) 111 self . SetStatusText ( " Click on column heading to sort " ) 112 113 menuBar = wxMenuBar ( ) ( ) 114 mainItem = wxMenu ( ) ( ) 115 AddMenuItem ( mainItem , " List 1 " , self , self . list1 ) 116 AddMenuItem ( mainItem , " List 2 " , self , self . list2 ) 117 menuBar . Append ( mainItem , ' &File ' ) 118 self . SetMenuBar ( menuBar ) 119 120 self . panel = DisplayRecordsCtrlPanel ( self ) 121 122 def list1 ( self , event = None ) : ) : 123 124 self . panel . columnNames = [ ' Company ' , ' City ' , ' Telephone 1 ' , ] = [, ] 125 self . panel . list . DeleteAllItems ( ) ( ) 126 rs = db . Execute ( ' select COMPANY, CITY, PHONE1, IDENTIFIER from CUSTOMERS where IDENTIFIER < 30 order by COMPANY ' ) 127 self . panel . CreateRecords ( rs ) 128 self . panel . PopulateList ( ) ( ) 129 130 def list2 ( self , event = None ) : ) : 131 132 self . panel . columnNames = [ ' Company ' , ' City ' , ] = [, ] 133 self . panel . list . DeleteAllItems ( ) ( ) 134 rs = db . Execute ( ' select COMPANY, CITY, PHONE1, IDENTIFIER from CUSTOMERS where IDENTIFIER < 30 order by COMPANY ' ) 135 self . panel . CreateRecords ( rs ) 136 self . panel . PopulateList ( ) ( ) 137 138 app = wxPySimpleApp ( ) ( ) 139 frame = MainFrame ( None , wxNewId (), ' Customers List ' ) (), 140 frame . Show ( ) ( ) 141 app . MainLoop ( ) ( )

I welcome your comments. Bill Bell