Listctrl sorting yields random Items

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Listctrl sorting yields random Items

franz steinhaeusler
Hello

If I click on Artist, I get some confusing orderings in the items.

Output of the console in the column sorter:
sort asc: True , col:  2
4 1
4 1
4 4
0 2
0 0
1 0
1 0
1 2
4 2
4 2


(but never indexes 5 or 3 are called)

If I click on Artist, it gives something like that (screenshot)

Whats wrong here (in my sample)?

Version info:
wxPython Version: 2.8.12.1
wxPython Platform: wxMSW, unicode, wx-assertions-on, SWIG-1.3.29
Python Version: 2.7.10.final

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

RandomOrderingListtrl.png (7K) Download Attachment
listctrldemosamplemodified.py (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Listctrl sorting yields random Items

Tim Roberts
franz steinhaeusler wrote:

If I click on Artist, I get some confusing orderings in the items.

Output of the console in the column sorter:
...
(but never indexes 5 or 3 are called)

If I click on Artist, it gives something like that (screenshot)

Whats wrong here (in my sample)?

You had a line in your code comments out that printed key and index in your creation loop.  If you has uncommented that, you might have seen the issue.

The problem is that you are using "key" and "index" as if they were interchangeable, and that is most definitely NOT the case.  The index of an item is its current position in the list, which changes all the time.  If you add
        print key, index, data
at the end of your creation loop, you'll see the following:

C:\tmp>py -2 x.py
1 0 ('Bad English', 'The Price Of Love', 'Rock')
2 1 ('DNA featuring Suzanne Vega', "Tom's Diner", 'Rock')
3 2 ('George Michael', 'Praying For Time', 'Rock')
4 0 ('A', 'L', 'Z')
5 4 ('Z', 'A', 'L')
6 4 ('L', 'Z', 'A')

Remember that you have turned on "sort ascending", so the control will create these items in sorted order.  The first three items are already in already in alphabetical order, so they get created as 0, 1, and 2.  The third item needs to go first, so it becomes index 0.  The fourth item needs to go last, so it becomes index 4.  The final item needs to go next to last, so it is also index 4

The reason you don't see 3 and 5 is that you never created items where the ItemData was 3 or 5.  Your six items will have ItemData of 0, 0, 1, 2, 4, 4.  Because you need to refer to your original ordering, you should use your key value, not the dynamic index value.  Use
        self.list.SetItemData( item, key )
instead of
        self.list.SetItemData( item, index )

Next, you should not do the sorting based on the column contents.  You should do the sorting based on your original data.  Instead of this:
        item1 = self.getColumnText (key1, self.nCol)
        item2 = self.getColumnText (key2, self.nCol)
do this:
        item1 = musicdata[key1][self.nCol]
        item2 = musicdata[key2][self.nCol]
-- 
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Listctrl sorting yields random Items

franz steinhaeusler
In reply to this post by franz steinhaeusler
Thank you, Tim, but none of your tips helped.

I have a seond example, this is really a riddle for me.
1) sorting is not ok
2) not with every every column click (and sort operation), the listctrl is updated.

Is that working on other wxPython versions? version 3 or the 4?

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

listctrldemosamplemodified2.py (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Listctrl sorting yields random Items

franz steinhaeusler

Now, I solved it with the columnsorter mixin.
Finally it works!
But it is still unclear for me, what was still wrong in the last attached sample.
I attach the new sample, I think, it is be much better now.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

listctrldemosamplemodifiedcolumnsorter.py (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Listctrl sorting yields random Items

Tim Roberts
In reply to this post by franz steinhaeusler
franz steinhaeusler wrote:
> Thank you, Tim, but none of your tips helped.

The code you attached doesn't include any of my tips.  At least, not
correctly.

        index = 0
        for text in testdata:
            idx = self.list.InsertStringItem(index, text[0])
            self.list.SetStringItem(index, 1, text[1])
            self.list.SetItemData(idx, idx)
            print idx, index, self.getColumnText(index, 0), self.getColumnText(index, 1)
            index += 1

You aren't thinking about what you're doing here.  InsertStringItem will
return to you the row where this entry ended up.  You need that number
so you know which list entry to modify, but that number has NOTHING to
do with the strings in your data array.  That "idx" value is going to
return 0, 1, 2, 0, 4, 4, just like before.  Even your debug print
statement is wrong; when you are talking to the list control, you need
to use idx, not index.  "index" is your number, "idx" is the list
control's number.

This should be correct, as I suggested before:

        for index, text in enumerate(testdata):
            idx = self.list.InsertStringItem(999, text[0])
            self.list.SetStringItem(idx, 1, text[1])
            self.list.SetItemData(idx, index)
            print idx, index, self.getColumnText(idx, 0), self.getColumnText(idx, 1)

So, the SetItemData needs to change entry number "idx", but the value we
need to remember is OUR value, "index".  That's the key point you don't
seem to get.  The ItemData maps from the list control's numbering to our
numbering.

    def columnSorter(self, key1, key2):
        if not self.sort_asc:
            key1, key2 = key2, key1
        #print key1, key2
        item1 = self.getColumnText(key1, self.nCol)
        item2 = self.getColumnText(key2, self.nCol)

This is still totally wrong, because you didn't include the code I
showed you..  You are treating the "key1" and "key2" values as if they
were row numbers in the list control, but that's NOT what you get.  What
you get is the item data that you stored with SetItemData.  It's YOUR
numbering, not the list control's row number.  You cannot pass those
numbers to getColumnText.  You have to look them up in YOUR array.

        item1 = testdata[key1][self.nCol]
        item2 = testdata[key2][self.nCol]

--
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.