[英]Overwritten TreeCtrl.OnCompareItems() not called in Python 3 - wxPython 4
I have a wx.TreeCtrl
structure where the user can sort the items by different criteria (date, name, id, descending, ascending, ...).我有一个wx.TreeCtrl
结构,用户可以在其中按不同的标准(日期、名称、ID、降序、升序等)对项目进行排序。 This worked fine in Python 2, but Python 3 (with wxPython 4) refuses sorting.这在 Python 2 中运行良好,但 Python 3(使用 wxPython 4)拒绝排序。 The method CTreeCtrl.OnCompareItems()
is called in Python 2, but never in Python 3. CTreeCtrl.OnCompareItems()
方法在 Python 2 中被调用,但从不在 Python 3 中被调用。
In the functools.cmp_to_key documentation ( https://docs.python.org/3/library/functools.html ) I found a hint: Python 3 does not support comparison functions.在 functools.cmp_to_key 文档 ( https://docs.python.org/3/library/functools.html ) 中,我发现了一个提示:Python 3 不支持比较函数。 Confusing: in the description of wx.TreeCtrl (wxPython 4) there is a comparison method OnCompareItems()
( https://docs.wxpython.org/wx.TreeCtrl.html#wx.TreeCtrl.OnCompareItems ).令人困惑:在 wx.TreeCtrl (wxPython 4) 的描述中有一个比较方法OnCompareItems()
( https://docs.wxpython.org/wx.TreeCtrl.html#wx.TreeCtrl.OnCompareItems )。 The description says, that together with this method I must use the RTTI macros DECLARE_DYNAMIC_CLASS
and IMPLEMENT_DYNAMIC_CLASS
since the baseclass does not know that I overwrote OnCompareItems()
.描述说,与此方法一起,我必须使用 RTTI 宏DECLARE_DYNAMIC_CLASS
和IMPLEMENT_DYNAMIC_CLASS
,因为基类不知道我覆盖OnCompareItems()
。 I found only descriptions of how to use this macros in C++, but nothing for python.我只找到了关于如何在 C++ 中使用这个宏的描述,但没有找到关于 python 的描述。
I have no idea how I could make my program calling my OnCompareItems()
method in Python3/wxPython 4.我不知道如何让我的程序在 Python3/wxPython 4 中调用我的OnCompareItems()
方法。
Can anybody help?有人可以帮忙吗?
Regards, Humbalan问候, 洪巴兰
Below there is a small sample programm which reflects the problem.下面有一个反映问题的小示例程序。 It runs with Python 2 and Python 3 as well.它也可以与 Python 2 和 Python 3 一起运行。 The print( 'in CTreeCtrl.OnCompareItems()' )
shows, that this method is called (in py2) or not called (in py3): print( 'in CTreeCtrl.OnCompareItems()' )
显示,此方法被调用(在 py2 中)或未被调用(在 py3 中):
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()
Edit (2018-03-08, 2:52pm)编辑 (2018-03-08, 2:52pm)
It seems that this is a bug in the c++ part of wxPython (see https://github.com/wxWidgets/Phoenix/issues/774 ) and the fix is still not available.这似乎是 wxPython 的 c++ 部分中的错误(请参阅https://github.com/wxWidgets/Phoenix/issues/774 )并且修复仍然不可用。
I had the same problem when attempting to sort customtreectrl items according to an arbitrary field, rather than only alphabetically as originally implemented.在尝试根据任意字段而不是仅按最初实现的字母顺序对 customtreectrl 项目进行排序时,我遇到了同样的问题。 I don't want to duplicate the comments above, except to say a fix now exists ( here , as given in @Humbalan's edit to their own question).我不想重复上面的评论,除了说现在存在修复(这里,如@Humbalan 对他们自己的问题的编辑中给出的)。
It's probably not worth providing a full example, as @Humbalan's question has plenty of detail, but in my case I create the tree items with something like this:可能不值得提供一个完整的例子,因为@Humbalan 的问题有很多细节,但在我的例子中,我用这样的东西创建树项目:
ctc_item = self.tree_ctc.AppendItem(ctc_parent, text = ctc_text, data = {'id_': ctc_id})
where self.tree_ctc = MyCustomTreeCtrl(self, style = some_style)
.其中self.tree_ctc = MyCustomTreeCtrl(self, style = some_style)
。 My tree control and (overridden) OnCompareItems() method are:我的树控件和(重写的)OnCompareItems() 方法是:
class MyCustomTreeCtrl(ctc.CustomTreeCtrl):
def __init__(self, parent, style):
ctc.CustomTreeCtrl.__init__(self, parent, agwStyle = style)
def OnCompareItems(self, item1, item2):
t1 = self.GetPyData(item1)['id_']
t2 = self.GetPyData(item2)['id_']
if t1 < t2: return -1
if t1 == t2: return 0
return 1
I realise the question is a couple of years old, but this is hopefully useful.我意识到这个问题已经有几年了,但希望这很有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.