我試圖在我的Mac Lion上使用Python腳本獲取剪貼板內容。剪貼板內容發生更改時觸發事件
我正在尋找一個事件或類似的東西,因爲如果我使用循環,我的應用程序將花費所有的時間來觀看剪貼板。
任何想法?
我試圖在我的Mac Lion上使用Python腳本獲取剪貼板內容。剪貼板內容發生更改時觸發事件
我正在尋找一個事件或類似的東西,因爲如果我使用循環,我的應用程序將花費所有的時間來觀看剪貼板。
任何想法?
你有沒有想過使用無限循環和嘗試之間的「睡眠」? 我用pyperclip做了一個簡單的PoC,它的功能就像一個魅力,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
,做你想做的。如果您需要多線程幫助將其放入後臺線程中,請告訴我。
EDIT
下面是一個完整的多線程例子。
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)
。
望着pyperclip
它的MacOSX上的肉:
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
這些工作對我來說你是怎麼得到的?
我不太關注你在循環中的評論。
編輯增加了「orrid輪詢的例子,說明如何changeCount()
每個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()
我正在使用Appkit框架:'NSPasteboard.generalPasteboard()',我需要循環來立即得到新的剪貼板內容..因爲我沒有剪貼板的回調事件。 –
的Python 3代碼(https://stackoverflow.com/a/14687465/4258588):
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)
PS-我不能爲它添加註釋由於低信譽分的話,我將以此爲回答。
這段代碼與之前發佈的代碼是99%相同的,唯一的區別是python3風格的'print()',並不真的值得單獨回答 – jps
謝謝,是請告訴我如何做到這一點在後臺線程我的循環看起來像這樣:'而真: \t \t \t pbstring = checkclipboard() \t \t \t如果的 'http://' 在pbstring和pbstring不是 'bit.ly': \t \t \t \t bitly(pbstring,用戶名,鍵) \t \t \t \t \t \t其他: \t \t \t \t打印的等待......「 \t \t \t \t打印pbstring \t \t \t \t time.sleep(5)'所以此刻我對循環整個應用程序等待,我不能同時做任何事情。 。 –
我創建了一個擴展示例,包括多線程。 –
你的腳本看起來不錯。你注意剪貼板中的URL,如果你找到了,用一個縮短的版本替換它? –