2013-02-04 38 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