challenge クリップボードへの転送

クリップボード(や同等の機能)へテキストを転送するプログラムをお願いします。 また可能でしたらクリップボードのデータを取り出すプログラムもお願いします。

システムに依存する内容ですが、応用範囲が広いと思いましたので出題させてもらいました。

Posted feedbacks - Python

私が使ってるライブラリそのものですが。私はこのコードを ocean/clipboard.py として保存してるので、

import ocean.clipboard as c
c.get() # クリップボードの中身を取得
c.set("hoge") # クリップボードに設定
c.clear() # クリップボードを空にする

として使います。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from __future__ import with_statement
from contextlib import contextmanager
import ctypes

GMEM_DDESHARE = 0x2000
GMEM_MOVEABLE = 0x0002
CF_TEXT = 1

user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32

@contextmanager
def _GlobalLock(h):
    p = kernel32.GlobalLock(h)
    if not p:
        raise WindowsError("GlobalLock() failed")
    try:
        yield p
    finally:
        kernel32.GlobalUnlock(h)

@contextmanager
def _Clipboard():
    if not user32.OpenClipboard(None):
        raise WindowsError("OpenClipboard() failed")
    try:
        yield
    finally:
        user32.CloseClipboard()

def set(s):
    s = s.encode("mbcs")
    # memory block
    h = kernel32.GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, len(s) + 1)
    if not h:
        raise WindowsError("GlobalAlloc() failed")
    try:
        with _GlobalLock(h) as p:
            p = (ctypes.c_char * (len(s) + 1)).from_address(p)
            for i, c in enumerate(s + "\0"):
                p[i] = c
        # clipboard
        with _Clipboard():
            user32.EmptyClipboard()
            user32.SetClipboardData(CF_TEXT, h)
    except:
        kernel32.GlobalFree(h)
        raise

def get():
    with _Clipboard():
        h = user32.GetClipboardData(CF_TEXT)
        if h:
            with _GlobalLock(h) as p:
                return ctypes.c_char_p(p).value.decode("mbcs")

def clear():
    with _Clipboard():
        user32.EmptyClipboard()

wxPythonのClipboard機能を試してみました。
プラットフォームに依存しないのがウリです。
windows xp, Centos5.1 gnome, Mac OS X Leopardで動作を確認しました。

らくちんすぎます。

コメント:
コードは、リンク先にあるwxpython.orgのコードを動くようにしただけです。

解説:
実行するとロードが跳ね上がります。
idle eventをhandleしてそこでTheClipboardの
内容をtext ctrlに貼り付けるだけ。
次のidle eventが処理されるので一瞬に
して消えます。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import wx

class MyFrame(wx.Frame):
  def __init__(self, parent, ID, title):
    wx.Frame.__init__(self, parent, ID, title, wx.DefaultPosition, wx.Size(200, 150))
    self.text = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.HSCROLL)
    wx.EVT_IDLE(self,self.Paste)

  def Paste(self, evt):
    do = wx.TextDataObject()
    success = str(wx.TheClipboard)
    if success:
      self.text.SetValue(do.GetText())
    else:
      self.text.SetValue("There is no data in the clipboard in the required format")

class MyApp(wx.App):
  def OnInit(self):
    frame = MyFrame(None, -1, "Hello from wxPython")
    frame.Show(True)
    self.SetTopWindow(frame)
    return True

app = MyApp(0)
app.MainLoop()

Index

Feed

Other

Link

Pathtraq

loading...