Unexpected characters appended to text strings when using wx.TextDropTarget

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

Unexpected characters appended to text strings when using wx.TextDropTarget

Alex
I am using wx.TextDropTarget to implement a drag and drop app where users can drag some text strings from a ListCtrl widget and drop them into TextCtrl widgets. One problem that I haven’t been able to figure out how to solve is that sometimes text strings dropped in TextCtrl widgets have random characters appended to the end (see screenshot below). This problem does not arise every single time – as you can see, “East of Eden” is displayed fine


I am on OSX 10.10.5 and using wxPython 2.9.2.4-1. I am not sure if this problem can be reproduced on other platforms. A sample code is below.

import wx

from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin

class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
   
def __init__(self, parent):
        wx
.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
       
ListCtrlAutoWidthMixin.__init__(self)


class TextDropTarget(wx.TextDropTarget):
   
def __init__(self, obj):
        wx
.TextDropTarget.__init__(self)
       
self.obj = obj

   
def OnDropText(self, x, y, text):
       
self.obj.WriteText(text)

   
def OnDragOver(self, x, y, d):
       
return wx.DragCopy


class MyApp(wx.Frame):
   
def __init__(self, parent, title):
       
super(MyApp, self).__init__(parent, style = wx.DEFAULT_FRAME_STYLE,
                            title
=title, size=(500, 500))
       
self.Panel = wx.Panel(self, size = (-1, -1))
       
GridBagSizer = wx.GridBagSizer(5,5)

       
#ListCtrl widget
       
self.Source = AutoWidthListCtrl(self.Panel)
       
self.Source.Show()
       
self.Source.InsertColumn(0, 'Book Titles')
       
self.Source.InsertStringItem(0,'War and Peace')
       
self.Source.InsertStringItem(0,'East of Eden')
       
self.Source.InsertStringItem(0,'Pride and Prejudice')

       
GridBagSizer.Add(self.Source, pos = (0, 0), span = (6, 1),
                         flag
= wx.EXPAND|wx.ALL, border = 15)
       
self.Panel.SetSizer(GridBagSizer)

       
#Label for each TextCtrl widget
       
AmericanNovel = wx.StaticText(self.Panel, label ="American Novel:")
       
EnglishNovel = wx.StaticText(self.Panel, label = "British Novel:")
       
RussianNovel = wx.StaticText(self.Panel, label = "Russian Novel:")      
       
GridBagSizer.Add(AmericanNovel, pos = (0, 1), span = (1, 1),
                         flag
= wx.TOP, border = 10)
       
GridBagSizer.Add(EnglishNovel, pos = (2, 1), span = (1, 1))
       
GridBagSizer.Add(RussianNovel, pos = (4, 1), span = (1, 1))                      

       
#TextCtrl widgets        
       
self.Target1 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)
       
self.Target2 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)
       
self.Target3 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)

       
GridBagSizer.Add(self.Target1, pos = (1, 1), span = (1, 1))
       
GridBagSizer.Add(self.Target2, pos = (3, 1), span = (1, 1))
       
GridBagSizer.Add(self.Target3, pos = (5, 1), span = (1, 1))                      

        dt1
= TextDropTarget(self.Target1)
        dt2
= TextDropTarget(self.Target2)
        dt3
= TextDropTarget(self.Target3)
       
self.Target1.SetDropTarget(dt1)
       
self.Target2.SetDropTarget(dt2)
       
self.Target3.SetDropTarget(dt3)

       
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)

       
GridBagSizer.AddGrowableCol(0)
       
GridBagSizer.AddGrowableCol(1)        


   
def OnDragInit(self, evt):
        text
= self.Source.GetItemText(evt.GetIndex())
        tdo
= wx.TextDataObject(text)
        tds
= wx.DropSource(self.Source)
        tds
.SetData(tdo)
        tds
.DoDragDrop(True)


if __name__ == "__main__":
    app
= wx.App()
   
MainFrame = MyApp(None, title = "My App")
   
MainFrame.Show()
   
MainFrame.Centre()
    app
.MainLoop()



Any pointer would be appreciated!

--
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: Unexpected characters appended to text strings when using wx.TextDropTarget

Dev Player
First validate "text", "tdo", "tds"  types in OnDragInit() with just print(type(text)) to be sure they are the expected types. Although it looks right to me it seems perhaps you are getting a "list item" object instead of the text string of the list item.

--
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: Unexpected characters appended to text strings when using wx.TextDropTarget

3vilguy
Hello there. I just started my adventure with wxPython and I have encountered exactly the same issue.
In app I'm trying to build you have many `TextCtrl` components and you should be able to copy text from one to another (using Right Mouse Button).
It's almost working, but I'm getting some extra characters while doing so.

I'm on OSX 10.13.3, using wxPython 4.0.1 and Python 2.7.10
Here's my code:

import wx
import wx.xrc


class TextDropTarget(wx.TextDropTarget):
   
def __init__(self, obj):
        wx
.TextDropTarget.__init__(self)
       
self.obj = obj

   
def OnDropText(self, x, y, data):
       
print "OnDropText"
        print data
       
print type(data)
       
self.obj.WriteText(data)
       
return True


class MainFrame(wx.Frame):
   
def __init__(self, parent):
        wx
.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition, size=wx.Size(500, 300), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)

       
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)

        b_sizer
= wx.BoxSizer(wx.VERTICAL)

       
for x in range(10):
            textCtrl
= wx.TextCtrl( self,
                                    wx.ID_ANY, wx.EmptyString,
                                    wx.DefaultPosition,
                                    wx.Size(-1, 40),
                                    wx.TE_MULTILINE
                       
)

            b_sizer
.Add(textCtrl, 0, wx.ALL | wx.EXPAND, 5)

            dt1
= TextDropTarget(textCtrl)
            textCtrl
.SetDropTarget(dt1)

            textCtrl
.Bind(wx.EVT_RIGHT_DOWN, self.OnDragInit)

       
self.SetSizer(b_sizer)
       
self.Centre(wx.BOTH)

   
def OnDragInit(self, event):
        tf
= event.GetEventObject()
        str
= tf.GetValue()
       
print str
       
print type(str)

        # Create a Text Data Object, which holds the text that is to be dragged
        tdo = wx.TextDataObject(str)

       
# Create a Drop Source Object, which enables the Drag operation
        tds = wx.DropSource(tf)

       
# Associate the Data to be dragged with the Drop Source Object
        tds.SetData(tdo)

       
# Initiate the Drag Operation
        tds.DoDragDrop(True)


if __name__ == '__main__':
    app
= wx.App(False)
    frame
= MainFrame(None).Show()
    app
.MainLoop()



Did I missed something obvious in here? Or there's some kind of bug?
The string seems fine in `OnDragInit` function, but when I'm printing data in `OnDropText` it already has the extra characters.
Just to be sure it's not something extra from the TextCtrl I even used hardcoded text for `TextDataObject` and still no luck.
What I also find weird it's very inconsistent. Sometimes it doesn't happen at all, then after restarting the app it does happen every single time. Also sometimes data in `OnDropText` function comes completely empty.

And one more thing I'm curious about is the `TextDataObject`.
I did something like:

tdo = wx.TextDataObject('123')
print tdo.GetText()
print tdo.GetTextLength()

and what is my console showing?
123
4

Shouldn't text length be 3 in this case?


Is anyone else struggling with such a things?


Best Regards,
3vilguy

--
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: Unexpected characters appended to text strings when using wx.TextDropTarget

Adrian Hill
In reply to this post by Alex
Alex,

Your code appears to run correctly under Windows 7, Python 3.5.2 and wxPython 4.0.1 msw (phoenix).
With the latest version of wxPython, function these deprecation warnings were reported:
34: wxPyDeprecationWarning: Call to deprecated item. Use InsertItem instead.
  self.Source.InsertStringItem(0,'War and Peace')
35: wxPyDeprecationWarning: Call to deprecated item. Use InsertItem instead.
  self.Source.InsertStringItem(0,'East of Eden')
36: wxPyDeprecationWarning: Call to deprecated item. Use InsertItem instead.
  self.Source.InsertStringItem(0,'Pride and Prejudice')

I made the suggested changes to use InsertItem().

Your code results in another warning:
TypeError: invalid result from TextDropTarget.OnDropText(), a 'bool' is expected not 'NoneType'
 but it still appears to run correctly.

This doesn't answer your original question, but does indicate that the code works on at least one combination of OS, Python and wxPython versions.




On Thursday, March 24, 2016 at 9:02:55 PM UTC-6, Alex wrote:
I am using wx.TextDropTarget to implement a drag and drop app where users can drag some text strings from a ListCtrl widget and drop them into TextCtrl widgets. One problem that I haven’t been able to figure out how to solve is that sometimes text strings dropped in TextCtrl widgets have random characters appended to the end (see screenshot below). This problem does not arise every single time – as you can see, “East of Eden” is displayed fine

<a style="margin-right:1em;margin-left:1em" href="http://i.stack.imgur.com/o4LUY.png" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fi.stack.imgur.com%2Fo4LUY.png\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLFUYDNl75Vbe8DQI8qroQKejnOg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fi.stack.imgur.com%2Fo4LUY.png\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFLFUYDNl75Vbe8DQI8qroQKejnOg&#39;;return true;">

I am on OSX 10.10.5 and using wxPython 2.9.2.4-1. I am not sure if this problem can be reproduced on other platforms. A sample code is below.

import wx

from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin

class AutoWidthListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
   
def __init__(self, parent):
        wx
.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
       
ListCtrlAutoWidthMixin.__init__(self)


class TextDropTarget(wx.TextDropTarget):
   
def __init__(self, obj):
        wx
.TextDropTarget.__init__(self)
       
self.obj = obj

   
def OnDropText(self, x, y, text):
       
self.obj.WriteText(text)

   
def OnDragOver(self, x, y, d):
       
return wx.DragCopy


class MyApp(wx.Frame):
   
def __init__(self, parent, title):
       
super(MyApp, self).__init__(parent, style = wx.DEFAULT_FRAME_STYLE,
                            title
=title, size=(500, 500))
       
self.Panel = wx.Panel(self, size = (-1, -1))
       
GridBagSizer = wx.GridBagSizer(5,5)

       
#ListCtrl widget
       
self.Source = AutoWidthListCtrl(self.Panel)
       
self.Source.Show()
       
self.Source.InsertColumn(0, 'Book Titles')
       
self.Source.InsertStringItem(0,'War and Peace')
       
self.Source.InsertStringItem(0,'East of Eden')
       
self.Source.InsertStringItem(0,'Pride and Prejudice')

       
GridBagSizer.Add(self.Source, pos = (0, 0), span = (6, 1),
                         flag
= wx.EXPAND|wx.ALL, border = 15)
       
self.Panel.SetSizer(GridBagSizer)

       
#Label for each TextCtrl widget
       
AmericanNovel = wx.StaticText(self.Panel, label ="American Novel:")
       
EnglishNovel = wx.StaticText(self.Panel, label = "British Novel:")
       
RussianNovel = wx.StaticText(self.Panel, label = "Russian Novel:")      
       
GridBagSizer.Add(AmericanNovel, pos = (0, 1), span = (1, 1),
                         flag
= wx.TOP, border = 10)
       
GridBagSizer.Add(EnglishNovel, pos = (2, 1), span = (1, 1))
       
GridBagSizer.Add(RussianNovel, pos = (4, 1), span = (1, 1))                      

       
#TextCtrl widgets        
       
self.Target1 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)
       
self.Target2 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)
       
self.Target3 = wx.TextCtrl(self.Panel, size = (240, -1),
                                   style
= wx.TE_READONLY)

       
GridBagSizer.Add(self.Target1, pos = (1, 1), span = (1, 1))
       
GridBagSizer.Add(self.Target2, pos = (3, 1), span = (1, 1))
       
GridBagSizer.Add(self.Target3, pos = (5, 1), span = (1, 1))                      

        dt1
= TextDropTarget(self.Target1)
        dt2
= TextDropTarget(self.Target2)
        dt3
= TextDropTarget(self.Target3)
       
self.Target1.SetDropTarget(dt1)
       
self.Target2.SetDropTarget(dt2)
       
self.Target3.SetDropTarget(dt3)

       
self.Bind(wx.EVT_LIST_BEGIN_DRAG, self.OnDragInit)

       
GridBagSizer.AddGrowableCol(0)
       
GridBagSizer.AddGrowableCol(1)        


   
def OnDragInit(self, evt):
        text
= self.Source.GetItemText(evt.GetIndex())
        tdo
= wx.TextDataObject(text)
        tds
= wx.DropSource(self.Source)
        tds
.SetData(tdo)
        tds
.DoDragDrop(True)


if __name__ == "__main__":
    app
= wx.App()
   
MainFrame = MyApp(None, title = "My App")
   
MainFrame.Show()
   
MainFrame.Centre()
    app
.MainLoop()



Any pointer would be appreciated!

--
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: Unexpected characters appended to text strings when using wx.TextDropTarget

Tim Roberts
In reply to this post by 3vilguy
3vilguy wrote:

And one more thing I'm curious about is the `TextDataObject`.
I did something like:

tdo = wx.TextDataObject('123')
print tdo.GetText()
print tdo.GetTextLength()

and what is my console showing?
123
4

Shouldn't text length be 3 in this case?

Did you read the documentation?
By default, returns the size of the text data set in the constructor or using SetText . This can be overridden to provide text size data on-demand. It is recommended to return the text length plus 1 for a trailing zero, but this is not strictly required.
-- 
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: Unexpected characters appended to text strings when using wx.TextDropTarget

3vilguy
Thanks Tim.

Yes, I saw the documentation, but to be fair "It is recommended to return" is not the same as "By default it returns..."
If that's the case then length 4 is nothing to be worried about, but the main problem (unexpected characters appended to text string) is still there.

Best Regards,
3vilguy

--
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.