Abgeleitetes TreeCtrl.OnCompareItems() wird in Python3/wxPython4 nicht aufgerufen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Benutzeravatar
Humbalan
User
Beiträge: 59
Registriert: Mittwoch 2. September 2009, 15:11

Hallo Forum,

ich habe eine wx.TreeCtrl-Struktur, bei der der User Items mit verschiedenen Kriterien sortieren kann (Datum, Name, ID, aufwärts, abwärts). Das hat gut in Python 2 funktioniert, aber Python 3 (mit wxPython 4) weigert sich zu sortieren. Die von mir überladene Methode CTreeCtrl.OnCompareItems() wird in Python 2 aufgerufen, nicht aber in Python 3.

In der Doku von functool.cmp_to_key() (https://docs.python.org/3/library/functools.html) fand ich einen Hinweis: Python 3 unterstützt keine Compare-Funktionen. Verwirrend: in der Beschreibung von wx.TrreeCtrl (wxPython 4) gibt es eine Vergleichsmethode OnCompareItems() (https://docs.wxpython.org/wx.TreeCtrl.h ... mpareItems). Die Beschreibung hier sagt zudem, das mit dieser Methode die RTTI Makros DECLARE_DYNAMIC_CLASS und IMPLEMENT_DYNAMIC_CLASS benutzt werden müssen, da die Basisklass nicht weiß, dass OnCompareItems() überladen wurde. Ich habe auch nur C++-Beispiele für die Anwendung dieser Makros gefunden, nichts für Python.

Ich habe nun keine Ahnung, wie ich nun mein Programm dazu bringen kann, das überladene OnCompareItems() in Python3/wxPython4 zu benutzen.

Kann jemand helfen?

Beste Grüße
Humbalan

Hier ist noch ein Minimalprogramm, um mein Problem reproduzieren zu können. Es läuft mit Python 2 und Python 3. Das print (in CTreeCtrl.OnCompareItems()) zeigt, ob die Methode aufgerufen wurde oder nicht.

Code: Alles auswählen

import sys
import wx

class CTreeCtrl( wx.TreeCtrl ):
    def __init__( self, parent ):
        super( CTreeCtrl, self ).__init__( parent=parent, style=wx.TR_HIDE_ROOT )

    def OnCompareItems( self, item1, item2 ):
        print( 'in CTreeCtrl.OnCompareItems()' )
        if sys.version_info.major < 3:
            d1 = self.GetItemData( item1 ).Data
            d2 = self.GetItemData( item2 ).Data
        else:
            d1 = self.GetItemData( item1 )
            d2 = self.GetItemData( item2 )

        if   d1 < d2:  return -1
        elif d1 > d2:  return 1
        else        :  return 0


class CSettingsTree( wx.Dialog  ):

    def __init__( self, parent, settings ) :

        size = wx.Size(200,150)

        wx.Dialog.__init__( self, parent, title='all settings', size=size )
        bSizer_main = wx.BoxSizer( wx.VERTICAL )

        self.m_treeCtrl = CTreeCtrl( self  )
        bSizer_main.Add( self.m_treeCtrl, 0, wx.ALL|wx.EXPAND, 5 )

        self.SetSizer( bSizer_main )
        bSizer_main.Fit( self )

        root = self.m_treeCtrl.AddRoot( 'Settings' )

        for key, name in settings :
            if sys.version_info.major < 3 :  sort_key = wx.TreeItemData( name )
            else                          :  sort_key = name

            self.m_treeCtrl.AppendItem( root, '{}: {}'.format(key, name), data=sort_key )

        self.m_treeCtrl.ExpandAll()
        self.m_treeCtrl.SortChildren( root )


#---------------------------------------------------------------------------
if __name__=="__main__":

    app = wx.App( redirect=False )

    settings = [(50,'Taylor'),(200,'Mueller'),(101,'Baker'),(102,'Smith')]

    dlg = CSettingsTree( wx.Frame( None ), settings )
    dlg.ShowModal()
Benutzeravatar
Humbalan
User
Beiträge: 59
Registriert: Mittwoch 2. September 2009, 15:11

Ich habe leider nicht herausgefunden, wie ich meinen Post editieren kann :K :oops: . Daher eine Ergänzung auf diesem Weg.

Es sieht so aus, als ob das beschreibene Verhalten ein Bug in wxPython 4 ist (sieh https://github.com/wxWidgets/Phoenix/issues/774). Leider ist ein Fix noch nicht erhältlich. Ganz schön hart :( .
Antworten