4
votes

I am using a ListCtrl as a log file viewer so that I can hide "debug" type of columns from the average user. I would like to be able to select multiple cells just like you can do in many other grid-type programs, and then right click and say "Copy", and then be able to paste that into a text doc, email, etc. I would like to be able to select any grouping of contiguous cells, rather than be limited to whole rows only.

Is there anything built-in that does this for me? How would I accomplish that? Should I switch to a virtual or ultimate ListCtrl? Maybe I should be using some other wxPython class?

1
Yes, I have looked at that, as well as Ultimate ListCtrl and Virtual. But that doesn't show me the way. I notice that the TextCtrl has a right-click popup for "free" in that it just appears when I use the ctrl. But I get no freebies with ListCtrl. Also, the selection is row-based in ListCtrl, but I would like selection that works more like the wxGrid. Maybe using wxGrid would get me closer? But that still doesn't get me the right-click with copy to clipboardDavid Lynch
wiki.wxpython.org/PopupMenuOnRightClick shows how to make a popup menu. wxGrid would probably work better if you need to select rows and columns.unddoch

1 Answers

3
votes

A working example:

import wx


class Frame(wx.Frame):

    def __init__(self):
        super(Frame, self).__init__(None, -1, "List copy test", size=(400, 500))

        panel = wx.Panel(self, -1)

        self.listCtrl = wx.ListCtrl(panel, -1, size=(200, 400), style=wx.LC_REPORT)
        self.listCtrl.InsertColumn(0, "Column 1", width=180)

        for i in xrange(10):
            self.listCtrl.InsertStringItem(i, "Item %d" % i)

        self.listCtrl.Bind(wx.EVT_RIGHT_UP, self.ShowPopup)


    def ShowPopup(self, event):
        menu = wx.Menu()
        menu.Append(1, "Copy selected items")
        menu.Bind(wx.EVT_MENU, self.CopyItems, id=1)
        self.PopupMenu(menu)


    def CopyItems(self, event):
        selectedItems = []
        for i in xrange(self.listCtrl.GetItemCount()):
            if self.listCtrl.IsSelected(i):
                selectedItems.append(self.listCtrl.GetItemText(i))

        clipdata = wx.TextDataObject()
        clipdata.SetText("\n".join(selectedItems))
        wx.TheClipboard.Open()
        wx.TheClipboard.SetData(clipdata)
        wx.TheClipboard.Close()

        print "Items are on the clipboard"


app = wx.App(redirect=False)
frame = Frame()
frame.Show()
app.MainLoop()

You mentioned a list control, but if you want to select multiple cells, perhaps a grid control (excel sheet like) might be more suitable. The idea is still the same only the part where the list items (or cell items) are collected is different.