Seite 1 von 1

Fehlerhaftes DragAndDrop in wx.TreeListCtrl

Verfasst: Dienstag 10. April 2007, 19:52
von HWK
Ich habe in einem Script für ein TreeListCtrl DragAndDrop implementiert. Unter Python 2.4.2 mit wxPython 2.6 funktionierte das wunderbar. Nach Update auf Python 2.4.4 und wxPython 2.8 nicht mehr. Bei EVT_TREE_BEGIN_DRAG wird scheinbar das Item übergeben, auf das der Cursor bewegt wird, und nicht das, von dem das Dragging startet. Auch wandert die Selection (die blau hinterlegte Zeile nicht mit). Googlen förderte schon ähnliche Probleme zu Tage, z.B.: http://archives.devshed.com/forums/pyth ... 23112.html. Kennt jemand das Problem und am besten auch die Lösung? Ansonsten: Wo kann man den mutmaßlichen Bug mitteilen? Die im o.g. Link vorgeschlagene Lösung, das selektierte Item zu verwenden, funktioniert nur z.T., weil ich gern das Start-Item markieren und die sich ändernde Selektion verfolgen möchte. Dies geht trotzdem nicht.
Hier ein bisschen Beispielcode zum Testen:

Code: Alles auswählen

import wx
import wx.gizmos as gizmos

class TestPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)
        self.DragItem = None
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.tree = gizmos.TreeListCtrl(self, -1, style = wx.TR_DEFAULT_STYLE
                                        | wx.TR_FULL_ROW_HIGHLIGHT)
        isz = (16,16)
        il = wx.ImageList(isz[0], isz[1])
        fldridx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, isz))
        fldropenidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_FILE_OPEN, wx.ART_OTHER, isz))
        self.fileidx = il.Add(wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, isz))
        self.tree.SetImageList(il)
        self.il = il
        self.tree.AddColumn("Main column")
        self.tree.SetMainColumn(0)
        self.tree.SetColumnWidth(0, 175)
        self.root = self.tree.AddRoot("The Root Item")
        self.tree.SetItemImage(self.root, fldridx, which = wx.TreeItemIcon_Normal)
        self.tree.SetItemImage(self.root, fldropenidx, which = wx.TreeItemIcon_Expanded)
        for x in range(15):
            txt = "Item %d" % x
            child = self.tree.AppendItem(self.root, txt)
            self.tree.SetItemImage(child, fldridx, which = wx.TreeItemIcon_Normal)
            self.tree.SetItemImage(child, fldropenidx, which = wx.TreeItemIcon_Expanded)
            for y in range(5):
                txt = "item %d-%s" % (x, chr(ord("a")+y))
                item = self.tree.AppendItem(child,  txt)
                self.tree.SetItemImage(item, self.fileidx, which = wx.TreeItemIcon_Normal)
                self.tree.SetItemImage(item, self.fileidx, which = wx.TreeItemIcon_Selected)
        self.tree.Expand(self.root)
        self.tree.Bind(wx.EVT_TREE_BEGIN_DRAG, self.OnBeginDrag)
        self.tree.Bind(wx.EVT_TREE_END_DRAG, self.OnEndDrag)

    def OnBeginDrag(self, evt):
        if not self.tree.ItemHasChildren(evt.GetItem()):
            evt.Allow()
            self.DragItem = evt.GetItem()
            print self.tree.GetItemText(self.DragItem)

    def OnEndDrag(self, evt):
        old = self.DragItem
        if old is None:
            return
        new_ = evt.GetItem()
        if not new_.IsOk() or new_ == old:
            return
        parent = self.tree.GetItemParent(new_)
        OldParent = self.tree.GetItemParent(old)
        if new_ != OldParent and parent != OldParent:
            self.tree.UnselectAll()
            self.tree.SelectItem(old)
            return
        text = self.tree.GetItemText(old, 0)
        self.tree.Delete(old)
        if new_ == OldParent:
            child = self.tree.InsertItemBefore(new_, 0, text)
        else:
            child = self.tree.InsertItem(parent, new_, text)
        self.tree.SetItemImage(child, self.fileidx,
                               which = wx.TreeItemIcon_Normal)
        self.tree.SetItemImage(child, self.fileidx,
                               which = wx.TreeItemIcon_Expanded)
        self.tree.SelectItem(child)
        self.DragItem = None

    def OnSize(self, evt):
        self.tree.SetSize(self.GetSize())

def main():
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, 'TreeListCtrl', size=(200, 400))
    panel = TestPanel(frame)
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()
Danke
HWK

Verfasst: Donnerstag 12. April 2007, 20:21
von HWK
_gizmos.pyd scheint sehr 'buggy' zu sein. Ich habe jetzt das Dragging per Hand nachgebildet. Damit sind die bisherigen Probleme behoben, es taucht aber wieder ein neues auf: Jetzt wird in meiner Routine für EVT_TREE_END_DRAG mit SelectItem ein völlig falsches Item selektiert.
Ich habe auch versucht, die alte _gizmos.pyd unter wxPython 2.8 zu verwenden. Sie benötigt aber Version 2.6.
Edit: Durch CallAfter kann ich jetzt zwar den richtigen Item selektieren, um den ehemals falsch selektierten bleibt aber ein schwarzer Rahmen zurück. Ich habe deshalb jetzt zusätzlich wxPython 2.6 installiert und wähle dies mit wxversion aus.
Das ist aber alles sehr unbefriedigend. Hier besteht doch dringender Handlungsbedarf zur Nachbesserung von _gizmos.pyd.
MfG
HWK

Verfasst: Donnerstag 12. April 2007, 22:45
von gerold
HWK hat geschrieben:Das ist aber alles sehr unbefriedigend. Hier besteht doch dringender Handlungsbedarf zur Nachbesserung von _gizmos.pyd.
Hallo HWK!

Diese Info läuft hier im Python-Forum komplett ins Leere. Das sollte in die wxPython-Mailingliste und dann brauchts noch einen Bug-Report. Nur dann ist Aussicht auf Verbesserung.

mfg
Gerold
:-)

Verfasst: Donnerstag 12. April 2007, 22:53
von gerold
Hallo HWK!

Vielleicht hat das etwas mit deinem Problem zu tun.
http://thread.gmane.org/gmane.comp.pyth ... ocus=46023
Keine Ahnung. Ich kann nicht so gut Englisch.

mfg
Gerold
:-)

Verfasst: Freitag 13. April 2007, 12:19
von HWK
Hallo, Gerold!
Danke für den Link. TreeMixin hatte ich aber schon an einer anderen Stelle gefunden. Ich habe es als Anregung für das manuelle Draggen verwendet. Dabei traten aber die genannten Probleme auf.
Einen Bug-Report habe ich mittlerweile erstellt. Ich hoffe, ich habe das richtig gemacht. War ja doch ein bisschen umständlich. Wo und wie ich das in die wxPython-Mailingliste bringen kann, weiß ich aber nicht.
Kannst Du mir da einen Tip geben?
Edit: Ich habe jetzt nochmal die Demo zu TreeMixin, die ich bisher noch nicht hatte, ausprobiert. Das Ergebnis ist wie in meiner aktuellen Variante: Es bleibt immer wieder ein störender schwarzer Rahmen zurück.
MfG
HWK

Verfasst: Freitag 13. April 2007, 13:03
von gerold
HWK hat geschrieben:Wo und wie ich das in die wxPython-Mailingliste bringen kann, weiß ich aber nicht.
HWK
Hallo HWK!

- http://wxpython.org/maillist.php
- http://www.python-forum.de/post-63303.html#63303

Bei Gmane http://news.gmane.org/gmane.comp.python.wxpython kann man die Mailingliste ziemlich gut nach Stichworten durchsuchen.

mfg
Gerold
:-)

Verfasst: Freitag 13. April 2007, 13:16
von HWK
Danke! Ich hab's gemailt.
MfG
HWK

Verfasst: Sonntag 22. April 2007, 09:51
von HWK
Als kurze Rückkopplung:
Die wxPython-Mail-List hat bisher auch nichts ergeben. Jemand hat einen weiteren Fehler in wx.TreeListCtrl berichtet: Multi-Selection lässt sich nicht abschalten. In seiner Mail hat er aber auch von den mir bereits aufgefallenen übrigbleibenden Rändern berichtet. Robin Dunn hat versprochen, sich dies einmal anzuschauen.
MfG
HWK