18

Mac Lion で Python スクリプトを使用してクリップボードの内容を取得しようとしています。

ループを使用すると、アプリケーションが常にクリップボードを監視しているため、イベントなどを探しています。

何か案は?

4

3 に答える 3

20

無限ループを使用して試行間で「スリープ」することを考えたことがありますか? 私は単純な PoC にpyperclipを使用しましたが、Windows と Linux は魅力的でした。

import time
import sys
import os
sys.path.append(os.path.abspath("SO_site-packages"))

import pyperclip

recent_value = ""
while True:
    tmp_value = pyperclip.paste()
    if tmp_value != recent_value:
        recent_value = tmp_value
        print("Value changed: %s" % str(recent_value)[:20])
    time.sleep(0.1)

の代わりに、print好きなことをしてください。これをバックグラウンド スレッドに入れるためにマルチスレッド化の助けが必要な場合は、教えてください。

編集

完全なマルチスレッドの例を次に示します。

import time
import threading

import pyperclip

def is_url_but_not_bitly(url):
    if url.startswith("http://") and not "bit.ly" in url:
        return True
    return False

def print_to_stdout(clipboard_content):
    print ("Found url: %s" % str(clipboard_content))

class ClipboardWatcher(threading.Thread):
    def __init__(self, predicate, callback, pause=5.):
        super(ClipboardWatcher, self).__init__()
        self._predicate = predicate
        self._callback = callback
        self._pause = pause
        self._stopping = False

    def run(self):       
        recent_value = ""
        while not self._stopping:
            tmp_value = pyperclip.paste()
            if tmp_value != recent_value:
                recent_value = tmp_value
                if self._predicate(recent_value):
                    self._callback(recent_value)
            time.sleep(self._pause)

    def stop(self):
        self._stopping = True

def main():
    watcher = ClipboardWatcher(is_url_but_not_bitly, 
                               print_to_stdout,
                               5.)
    watcher.start()
    while True:
        try:
            print("Waiting for changed clipboard...")
            time.sleep(10)
        except KeyboardInterrupt:
            watcher.stop()
            break


if __name__ == "__main__":
    main()

threading.Thread のサブクラスを作成し、メソッドrunをオーバーライドして__init__、このクラスのインスタンスを作成します。watcher.start()(ではなくrun()!)を呼び出すことで、スレッドを開始します。

スレッドを安全に停止するには、-c (キーボード割り込み) を待って、スレッド自体を停止するように指示します。

クラスの初期化には、pause試行間の待機時間を制御するパラメーターもあります。

私の例のようにClipboardWatcherクラスを使用し、コールバックをあなたがすること、例えばlambda x: bitly(x, username, password).

于 2013-02-04T13:09:53.007 に答える
2

pyperclipMacosx でその本質を見ると、次のようになります。

import os
def macSetClipboard(text):
    outf = os.popen('pbcopy', 'w')
    outf.write(text)
    outf.close()

def macGetClipboard():
    outf = os.popen('pbpaste', 'r')
    content = outf.read()
    outf.close()
    return content

これらは私のために働いています。

ループに陥っているというあなたのコメントにはあまり従いません。


編集changeCount()ペーストボードにそれぞれがどのようにぶつかるかを示す「orrid polling example」を追加しましcopyた。への変更に関するイベントや通知がないように見えるため、OPが望んでいるものではありませんNSPasteboard

from LaunchServices import *
from AppKit import *
import os

from threading import Timer

def poll_clipboard():
    pasteboard = NSPasteboard.generalPasteboard()
    print pasteboard.changeCount()

def main():
    while True:
        t = Timer(1, poll_clipboard)
        t.start()
        t.join()

if __name__ == "__main__":
    main()
于 2013-02-04T13:45:21.903 に答える