1

Hi I am new to python and I am self taught programmer otherwise.

I am trying to get the copy and paste methods working for the clipboard in wxpython.

I have found and implemented what I have found on the topic, but there is an issue when used on my mac computer (OS X 10.10.5).

The attached code is a sample application that works fine within itself (given limits of grid). It also works fine for copying from the grid cells and pasting to an external notepad or spreadsheet. Meaning to me that the SetData is getting and maintaining the tab delimiters and new lines when building the clipboard data.

However, if I select tab delimited and multiline data from the same notepad or spreadsheet and proceed to paste into the grid, I get a single column of data. This means to me that the tab delimiters and newline characters are lost in the GetData.

With a data selection of

1 2 3

4 5 6

in a spreadsheet.

Using print repr(data) to get what the clipboard is holding, as suggested, When copying and pasting within application results in pasting data - print repr(data) = u'1\t2\t3\n4\t5\t6\n'

When data is copied from an external source and pasting seems to only have \r return characters and ufeff ?? which I don't know about? Perhaps thats a key? (on the mac)

print repr(data) = u'\ufeff\r1\r2\r3\r4\r5\r6\r\r'

Now this works fine on my Windows machine, but not on my Mac.

Is this a known issue? Is there a workaround, or is there a setting that I am missing or that I don't understand?

Much appreciate any help or direction. Thanks Frank

import wx
import wx.grid as dg



class cp(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, wx.ID_ANY, size = (600,600))

        self.dgGrid = dg.Grid(self, size = (500,500))
        self.dgGrid.CreateGrid(10,5)

        self.dgGrid.Bind(wx.EVT_KEY_DOWN, self.OnKeyPress)



    def OnKeyPress(self, event):

        # If Ctrl+V is pressed...
        if event.ControlDown() and event.GetKeyCode() == 86:
            print "Ctrl+V"
            # Call paste method
            self.Paste()
        if event.ControlDown() and event.GetKeyCode() == 67:
            print "Ctrl+C"
            # Call copy method
            self.copy()     

        event.Skip()    

    def copy(self):
        print "Copy method"
        # Number of rows and cols
        rows = self.dgGrid.GetSelectionBlockBottomRight()[0][0] - self.dgGrid.GetSelectionBlockTopLeft()[0][0] + 1
        cols = self.dgGrid.GetSelectionBlockBottomRight()[0][1] - self.dgGrid.GetSelectionBlockTopLeft()[0][1] + 1

        # data variable contain text that must be set in the clipboard
        data = ''

        # For each cell in selected range append the cell value in the data variable
        # Tabs '\t' for cols and '\r' for rows
        for r in range(rows):
            for c in range(cols):
                data = data + str(self.dgGrid.GetCellValue(self.dgGrid.GetSelectionBlockTopLeft()[0][0] + r, self.dgGrid.GetSelectionBlockTopLeft()[0][1] + c))
                if c < cols - 1:
                    data = data + '\t'
            data = data + '\n'
        # Create text data object
        clipboard = wx.TextDataObject()
        # Set data object value
        clipboard.SetText(data)
        # Put the data in the clipboard
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(clipboard)
            wx.TheClipboard.Close()
        else:
            wx.MessageBox("Can't open the clipboard", "Error")



    def Paste(self):
        print "Paste method"
        clipboard = wx.TextDataObject()


        if wx.TheClipboard.Open():
            wx.TheClipboard.GetData(clipboard)
            wx.TheClipboard.Close()
        else:
            wx.MessageBox("Can't open the clipboard", "Error")
            return

        data = clipboard.GetText()

        y = -1
        # Convert text in a array of lines
        for r in data.splitlines():
            y = y +1
            x = -1
            print r
            # Convert c in a array of text separated by tab
            for c in r.split('\t'):
                x = x +1
                print c
                self.dgGrid.SetCellValue(self.dgGrid.GetGridCursorRow() + y, self.dgGrid.GetGridCursorCol() + x, c)


if __name__ == '__main__':
    print ' running locally not imported '


    app = wx.App(False)
    MainFrame = wx.Frame(None, title = "TestingCopy and Paste", size = (600,600))


    cppanel = cp(MainFrame)

    MainFrame.Refresh()


    MainFrame.Show()

    app.MainLoop()
Frank
  • 59
  • 5
  • You should try `print repr(data)` to see what you really got from the clipboard. – Mark Ransom Jan 01 '16 at 18:08
  • Thanks Mark, I have added the repr(data) and updated my question with the results. I have also used the clipboard viewer that is available in OSX and the contents of the clipboard are as they should be. – Frank Jan 02 '16 at 21:07
  • `'\ufeff'` is a [Byte Order Mark](https://en.wikipedia.org/wiki/Byte_order_mark) and can be safely ignored. As for the rest I don't know, since `splitlines()` splits them just fine. – Mark Ransom Jan 02 '16 at 21:13

0 Answers0