can anyone help to fix the bugs in my code?

thanks in advance. I have tried to kill the bugs for several days, but
I found nothing useful :frowning:

what I want:
1. the text in every cell fill the cell from the left
2. the row is displayed in white-grey-white-... color, so make it
clear, that is true when I delete a row
3. there is always a row is selected, and the color for a selected row
is blue. when I delete a row, the nearest is selected

What I get now:
1. there is an extra space before name,
http://www.lusiya.com/ofstar/attachments/9_1120_1240664356.gif

2. when I delete a row, no row is shown as selected
3. when I delete a row, the color for rows get into a messy
http://www.lusiya.com/ofstar/attachments/9_1120_1240664687.gif
http://www.lusiya.com/ofstar/attachments/9_1120_1240665022.gif

here is the code, which use the images.py who comes with official wxpython demo
and sorry if the code is some long for a maillist

[code]
import wx
import wx.lib.mixins.listctrl as listmix
import images

musicdata = {
1 : ["Bad English", "The Price Of Love", "Rock"],
2 : ["DNA featuring Suzanne Vega", "Tom's Diner", "Rock"],
3 : ["George Michael", "Praying For Time", "Rock"],
4 : ["Gloria Estefan", "Here We Are", "Rock"],
5 : ["Linda Ronstadt", "Don't Know Much", "Rock"],
6 : ["Michael Bolton", "How Am I Supposed To Live Without You", "Blues"],
}
datacol=len(musicdata)

class TestListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
    def __init__(self, parent, ID, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=0):
        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
        listmix.ListCtrlAutoWidthMixin.__init__(self)

class ListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
        sizer = wx.BoxSizer(wx.VERTICAL)

        if wx.Platform == "__WXMAC__" and \
               hasattr(wx.GetApp().GetTopWindow(), "LoadDemo"):
            self.useNative = wx.CheckBox(self, -1, "Use native listctrl")
            self.useNative.SetValue(
                not
wx.SystemOptions.GetOptionInt("mac.listctrl.always_use_generic") )
            self.Bind(wx.EVT_CHECKBOX, self.OnUseNative, self.useNative)
            sizer.Add(self.useNative, 0, wx.ALL | wx.ALIGN_RIGHT, 4)

        self.il = wx.ImageList(16, 16)

        self.sm_up = self.il.Add(images.SmallUpArrow.GetBitmap())
        self.sm_dn = self.il.Add(images.SmallDnArrow.GetBitmap())

        self.list = TestListCtrl(self, -1,
                                 style=wx.LC_REPORT
                                 > wx.LC_SORT_ASCENDING
                                 > wx.LC_VRULES
                                 > wx.LC_HRULES
                                 > wx.LC_SINGLE_SEL
                                 )

        self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
        sizer.Add(self.list, 1, wx.EXPAND)

        self.PopulateList()

        # Now that the list exists we can init the other base class,
        # see wx/lib/mixins/listctrl.py
        self.itemDataMap = musicdata
        listmix.ColumnSorterMixin.__init__(self, datacol)
        self.SortListItems(0, True)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)

        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
        self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self.list)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
        self.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete, self.list)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)

    def OnUseNative(self, event):
        wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic",
not event.IsChecked())
        wx.GetApp().GetTopWindow().LoadDemo("ListCtrl")

    def PopulateList(self):
        self.list.InsertColumn(0, "Artist", wx.LIST_FORMAT_RIGHT)
        self.list.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT)
        self.list.InsertColumn(2, "Genre")

        items = musicdata.items()
        for key, data in items:
            index=self.list.InsertStringItem(20000, data[0])
            self.list.SetStringItem(index, 1, data[1])
            self.list.SetStringItem(index, 2, data[2])
            self.list.SetItemData(index, key)

        self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
        self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
        self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)

        # show how to select an item
        self.list.SetItemState(0, wx.LIST_STATE_SELECTED,
wx.LIST_STATE_SELECTED)

        self.ChangeColor()
        self.currentItem = 0

    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetListCtrl(self):
        return self.list

    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
    def GetSortImages(self):
        return (self.sm_dn, self.sm_up)

    def getColumnText(self, index, col):
        item = self.list.GetItem(index, col)
        return item.GetText()

    def OnItemSelected(self, event):
        ##print event.GetItem().GetTextColour()
        self.currentItem = event.m_itemIndex
        print("OnItemSelected: index=%s, line=%s, %s, %s, %s\n" %
                           (self.list.GetItemData(self.currentItem),
                            self.currentItem+1,
                            self.list.GetItemText(self.currentItem),
                            self.getColumnText(self.currentItem, 1),
                            self.getColumnText(self.currentItem, 2)))

        event.Skip()

    def OnItemDeselected(self, evt):
        item = evt.GetItem()
        print("OnItemDeselected: %d" % evt.m_itemIndex)

    def OnItemActivated(self, event):
        self.currentItem = event.m_itemIndex
        print("OnItemActivated: %s\nTopItem: %s" %
                           (self.list.GetItemText(self.currentItem),
self.list.GetTopItem()))

    def OnItemDelete(self, event):
        print("OnItemDelete\n")

    def OnColClick(self, event):
        print("OnColClick: %d\n" % event.GetColumn())
        self.ChangeColor()
        event.Skip()

    def ChangeColor(self):
        self.list.Refresh()
        numItem=self.list.GetItemCount()
        print 'numItem=', numItem
        for i in range(0, numItem, 2):
            item = self.list.GetItem(i)
            item.SetBackgroundColour(wx.WHITE)
            self.list.SetItem(item)

        for i in range(1, numItem, 2):
            item = self.list.GetItem(i)
            item.SetBackgroundColour((179,179,179))
            self.list.SetItem(item)
        self.list.Refresh()

class MyDialog(wx.Dialog):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyDialog.__init__
        kwds["style"] =
wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.THICK_FRAME|wx.FULL_REPAINT_ON_RESIZE
        wx.Dialog.__init__(self, *args, **kwds)
        self.lstPanel = ListCtrlPanel(self)
        self.static_line_2 = wx.StaticLine(self, -1, style=wx.LI_VERTICAL)
        self.btnAdd = wx.Button(self, -1, "Add")
        self.btnDel = wx.Button(self, -1, "Del")
        self.static_line_1 = wx.StaticLine(self, -1)
        self.label_1 = wx.StaticText(self, -1, "Name")
        self.txtName = wx.TextCtrl(self, -1, "")
        self.label_2 = wx.StaticText(self, -1, "Title")
        self.txtDate = wx.TextCtrl(self, -1, "")
        self.label_3 = wx.StaticText(self, -1, "Kind")
        self.txtEmail = wx.TextCtrl(self, -1, "")

        self.__set_properties()
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.onBtnDel, self.btnDel)
        # end wxGlade

        self.lstPanel.Bind(wx.EVT_LIST_DELETE_ITEM, self.OnItemDelete,
self.lstPanel.list)
        self.lstPanel.Bind(wx.EVT_LIST_ITEM_SELECTED,
self.OnItemSelected, self.lstPanel.list)

    def __set_properties(self):
        # begin wxGlade: MyDialog.__set_properties
        self.SetSize((640, 480))
        # end wxGlade
        self.PopulateForm()

    def OnSelectLst(self, evt):
        print 'in OnSelectLst'

    def OnItemDelete(self,evt):
        print 'in OnItemDelete'
        self.lstPanel.ChangeColor()
        self.lstPanel.list.Refresh()

    def OnItemSelected(self, evt):
        self.lstPanel.OnItemSelected(evt)
        self.PopulateForm()
        #print 'in =OnItemSelected'

    def PopulateForm(self):
        print 'self.lstPanel.list.GetItemCount()=',
self.lstPanel.list.GetItemCount()
        if self.lstPanel.list.GetItemCount():
            self.currentItem = self.lstPanel.currentItem
            self.txtName.SetValue(self.lstPanel.list.GetItemText(self.currentItem))
            self.txtDate.SetValue(self.lstPanel.getColumnText(self.currentItem,
1))
            self.txtEmail.SetValue(self.lstPanel.getColumnText(self.currentItem,
2))
        else:
            self.txtName.ChangeValue('')
            self.txtDate.ChangeValue('')
            self.txtEmail.ChangeValue('')

    def __do_layout(self):
        # begin wxGlade: MyDialog.__do_layout
        sizerMain = wx.FlexGridSizer(3, 1, 0, 0)
        sizerInfo = wx.FlexGridSizer(3, 2, 0, 0)
        grid_sizer_1 = wx.FlexGridSizer(1, 3, 0, 0)
        grid_sizer_2 = wx.FlexGridSizer(2, 1, 0, 0)
        grid_sizer_1.Add(self.lstPanel, 1, wx.EXPAND, 1)
        grid_sizer_1.Add(self.static_line_2, 0, wx.EXPAND, 0)
        grid_sizer_2.Add(self.btnAdd, 0, 0, 0)
        grid_sizer_2.Add(self.btnDel, 0, 0, 0)
        grid_sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 1)
        grid_sizer_1.AddGrowableRow(0)
        grid_sizer_1.AddGrowableCol(0)
        grid_sizer_2.AddGrowableCol(0)
        sizerMain.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        sizerMain.Add(self.static_line_1, 0, wx.EXPAND, 0)
        sizerInfo.Add(self.label_1, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizerInfo.Add(self.txtName, 0, wx.EXPAND, 0)
        sizerInfo.Add(self.label_2, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizerInfo.Add(self.txtDate, 0, wx.EXPAND, 0)
        sizerInfo.Add(self.label_3, 0, wx.ALIGN_CENTER_VERTICAL, 0)
        sizerInfo.Add(self.txtEmail, 0, wx.EXPAND, 0)
        sizerInfo.AddGrowableRow(0)
        sizerInfo.AddGrowableRow(1)
        sizerInfo.AddGrowableRow(2)
        sizerInfo.AddGrowableCol(1)
        sizerMain.Add(sizerInfo, 1, wx.LEFT|wx.RIGHT|wx.EXPAND, 5)
        self.SetSizer(sizerMain)
        sizerMain.AddGrowableRow(0)
        sizerMain.AddGrowableRow(2)
        sizerMain.AddGrowableCol(0)
        self.Center()
        self.Layout()
        # end wxGlade

    def showDict(self, aDict):
        keys=aDict.keys()
        keys.sort()
        for i in keys:
            print '%2s ---> %s' %(i, aDict[i])
        print

    def onBtnDel(self, event): # wxGlade: MyDialog.<event_handler>
        print "in Event handler `onBtnDel'"

        self.currentItem = self.lstPanel.currentItem
        print 'self.currentItem=%i,
self.lstPanel.list.GetItemCount()=%i' %(self.currentItem,
self.lstPanel.list.GetItemCount())

        self.showDict(musicdata)

        self.lstPanel.currentItem=self.lstPanel.currentItem-1

        musicdata.pop(self.lstPanel.list.GetItemData(self.currentItem))
        self.lstPanel.list.DeleteItem(self.currentItem)

        self.currentItem=self.currentItem -1
        if self.currentItem==-1:
            self.currentItem=0

        self.showDict(musicdata)

        if self.lstPanel.list.GetItemCount():
            print 'self.currentItem=%i,
self.lstPanel.list.GetItemCount()=%i' %(self.currentItem,
self.lstPanel.list.GetItemCount())
            self.lstPanel.list.SetItemState(self.currentItem,
wx.LIST_STATE_SELECTED|wx.LIST_STATE_FOCUSED, wx.LIST_STATE_SELECTED)
            self.lstPanel.list.Select(self.currentItem)
        else:
            self.btnDel.Enable(False)

        self.lstPanel.ChangeColor()
        self.lstPanel.Refresh()
# end of class MyDialog

class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        dlgMain = MyDialog(None, -1, "")
        self.SetTopWindow(dlgMain)
        dlgMain.Show()
        return 1

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
[/code]
[/code]

Hi oyster and All,

thanks in advance. I have tried to kill the bugs for several days, but
I found nothing useful :frowning:

what I want:
1. the text in every cell fill the cell from the left
2. the row is displayed in white-grey-white-... color, so make it
clear, that is true when I delete a row
3. there is always a row is selected, and the color for a selected row
is blue. when I delete a row, the nearest is selected

What I get now:
1. there is an extra space before name,
http://www.lusiya.com/ofstar/attachments/9_1120_1240664356.gif

I think this is a well-known consequence of using an image with a
wxListCtrl. I could be wrong, though.

I don't know how to answer the questions about the other issues. But,
it sounds like you're trying to re-invent ObjectListView.

Look over the FAQ for OLV: Frequently Asked Questions — ObjectListView v1.2 documentation

The example for OLV constructs a music list. Perhaps it'll help, and
save you some time in the process.
http://objectlistview.sourceforge.net/python/gettingStarted.html

I have not used OLV yet, myself, but I plan to.

I hope this helps.

Cheers,
Scott.

···

On Sat, Apr 25, 2009 at 9:19 AM, oyster <lepto.python@gmail.com> wrote:

grunculus wrote:

Hi oyster and All,

thanks in advance. I have tried to kill the bugs for several days, but
I found nothing useful :frowning:

what I want:
1. the text in every cell fill the cell from the left
2. the row is displayed in white-grey-white-... color, so make it
clear, that is true when I delete a row
3. there is always a row is selected, and the color for a selected row
is blue. when I delete a row, the nearest is selected

What I get now:
1. there is an extra space before name,
http://www.lusiya.com/ofstar/attachments/9_1120_1240664356.gif

I think this is a well-known consequence of using an image with a
wxListCtrl. I could be wrong, though.

You are right. The native control on Windows will reserve space for an icon if the control has an image list, it is assuming that you will eventually need to put an icon there. (Yay microsoft!)

···

On Sat, Apr 25, 2009 at 9:19 AM, oyster <lepto.python@gmail.com> wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!