2013-02-04 69 views

回答

16

你有沒有想過使用無限循環和嘗試之間的「睡眠」? 我用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)

+0

謝謝,是請告訴我如何做到這一點在後臺線程我的循環看起來像這樣:'而真: \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)'所以此刻我對循環整個應用程序等待,我不能同時做任何事情。 。 –

+0

我創建了一個擴展示例,包括多線程。 –

+0

你的腳本看起來不錯。你注意剪貼板中的URL,如果你找到了,用一個縮短的版本替換它? –

0

望着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() 
+0

我正在使用Appkit框架:'NSPasteboard.generalPasteboard()',我需要循環來立即得到新的剪貼板內容..因爲我沒有剪貼板的回調事件。 –

1

的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-我不能爲它添加註釋由於低信譽分的話,我將以此爲回答。

+1

這段代碼與之前發佈的代碼是99%相同的,唯一的區別是python3風格的'print()',並不真的值得單獨回答 – jps