wxPython ListCtrlで表示した行を選択してクリップボードに貼り付ける

2011/01/25

wx.ListCtrlで表を表示して、選択した行をクリップボードへ貼り付けてみる

表をソートしたら必要な行だけ選択して、他のアプリケーションで使いたいときがある。こんなときのために使えるサンプルを作ってみた。
マウス、キーボードで行を選択したら、copyボタンをクリック。メモ帳に貼り付けてみた。

クリップボード貼り付けするには wx.Clipboardクラスが準備されており、便利に使える。

選択した行を判断するには、wx.ListItemクラスのGetState()メソッドで、Itemの状態(state)を取得する。状態はビットマップで表現されており、wx.LIST_STATE_SELECTEDとAND演算して判断する。

item.GetState() & wx.LIST_STATE_SELECTED

#!/usr/bin/env python
#coding:utf-8

import wx

caption = (u"No",u"都道府県",u"男女計",u"男",u"女")

data = [
(1,u"北海道",5570,2638,2933),
(2,u"青森県",1407,663,744),
(3,u"岩手県",1364,652,712),
(4,u"宮城県",2347,1140,1208),
(5,u"秋田県",1121,527,593),
(6,u"山形県",1198,575,623),
(7,u"福島県",2067,1004,1063),
(8,u"茨城県",2969,1477,1492),
(9,u"栃木県",2014,1001,1013),
(10,u"群馬県",2016,993,1024),
(11,u"埼玉県",7090,3570,3520),
(12,u"千葉県",6098,3047,3051),
(13,u"東京都",12758,6354,6405),
(14,u"神奈川県",8880,4484,4396),
]

class MyTable(wx.ListCtrl):
    def __init__(self,parent):
        wx.ListCtrl.__init__(self,parent,-1,style = wx.LC_REPORT | wx.LC_VIRTUAL)
        self.InsertColumn(0,caption[0],wx.LIST_FORMAT_RIGHT)
        self.InsertColumn(1,caption[1])
        self.InsertColumn(2,caption[2],wx.LIST_FORMAT_RIGHT)
        self.InsertColumn(3,caption[3],wx.LIST_FORMAT_RIGHT)
        self.InsertColumn(4,caption[4],wx.LIST_FORMAT_RIGHT)
        self.items=data
        self.SetItemCount(len(self.items))
        self.Bind(wx.EVT_LIST_COL_CLICK,self.Sort)
        self.prevColumn = None
        self.sortAcend = True

    def OnGetItemText(self,line,col):
        return self.items[line][col]

    def Sort(self,event):
        col=event.GetColumn()
        if col != self.prevColumn:
            self.sortAcend = True
        else:
            if self.sortAcend:
                self.sortAcend = None
            else:
                self.sortAcend = True
        if self.sortAcend:
            self.items.sort(lambda x,y: cmp(x[col],y[col]))
        else:
            self.items.sort(lambda x,y: cmp(y[col],x[col]))
        self.prevColumn = col
        self.DeleteAllItems()
        self.SetItemCount(len(self.items))

class MyWindow(wx.Frame):
    def __init__(self,parent,id):
        wx.Frame.__init__(self, parent, id, u"コピーの実験", size=(450,300))
        self.copyBtn = wx.Button(self,-1,u"copy")
        self.tbl = MyTable(self)
        sz = wx.BoxSizer(wx.VERTICAL)
        sz.Add(self.copyBtn,0)
        sz.Add(self.tbl,1,wx.EXPAND)
        self.SetSizer(sz)
        self.Bind(wx.EVT_BUTTON, self.OnCopyBtn, self.copyBtn)

    def OnCopyBtn(self,event):
        if not wx.TheClipboard.Open():
            wx.MessageBox(u"クリップボードにコピーできません")
            return
        text = ""
        for i in range(self.tbl.GetItemCount()):
            item = self.tbl.GetItem(i)
            if item.GetState() & wx.LIST_STATE_SELECTED:
                d = self.tbl.items[i]
                text += str(d[0])+' '+d[1]+' '+str(d[2])+' '+str(d[3])+' '+str(d[4])+'\r\n'
        do = wx.TextDataObject(text)
        wx.TheClipboard.SetData(do)
        wx.TheClipboard.Close()

if __name__=='__main__':
    app=wx.PySimpleApp()
    frame=MyWindow(parent=None,id=-1)
    frame.Show()
    app.MainLoop()

実行すると

「男女計」の部分をクリックして昇順にソートする。

男女計が少ない都道府県を5つ選択して、copyボタンをクリックして、クリップボードにコピーする。

gedit(メモ帳)を起動して貼り付ける。

参考

wxPython

Posted by skw