2013-02-04 119 views
8

मैं अपने मैक शेर पर पाइथन स्क्रिप्ट का उपयोग करके क्लिपबोर्ड सामग्री प्राप्त करने का प्रयास कर रहा हूं।क्लिपबोर्ड सामग्री बदलते समय एक ईवेंट ट्रिगर करें

मैं एक घटना या कुछ इसी तरह की खोज कर रहा हूं, क्योंकि अगर मैं लूप का उपयोग करता हूं, तो मेरा एप्लिकेशन क्लिपबोर्ड को देखने में अपना पूरा समय बिताता है।

कोई विचार?

उत्तर

16

क्या आपने एक अंतहीन पाश और कोशिशों के बीच "सोने" का उपयोग करने के बारे में सोचा है? मैंने एक साधारण पीओसी के लिए pyperclip का उपयोग किया और यह एक आकर्षण, और विंडोज और लिनक्स की तरह काम करता था।

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 पैरामीटर भी है ताकि यह नियंत्रित किया जा सके कि प्रयासों के बीच कितना इंतजार करना है।

क्लासबोर्ड वाटर का उपयोग अपने उदाहरण की तरह करें, कॉलबैक को अपने द्वारा किए गए कार्यों के साथ बदलें, उदाहरण के लिए, 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 प्रिंट pbstring \t \t \t \t time.sleep (5) 'पल पाश के लिए मेरा पूरा एप्लिकेशन प्रतीक्षा करता है तो और मैं एक साथ कुछ भी नहीं कर सकता है। –

+0

मैंने मल्टीथ्रेडिंग समेत एक विस्तारित उदाहरण बनाया है। –

+0

आपकी स्क्रिप्ट एक अच्छा विचार की तरह लगती है। आप क्लिपबोर्ड में यूआरएल के लिए देखते हैं और, यदि आपको कोई मिलता है, तो इसे एक छोटे संस्करण के साथ बदलें? –

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 पर मुलाकात। ओपी चाहता है कि ओपी चाहता है क्योंकि 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

मैं एपकिट फ्रेमवर्क का उपयोग कर रहा हूं: 'NSPasteboard.generalPasteboard() ', मुझे तुरंत नए क्लिपबोर्ड सामग्री प्राप्त करने के लिए लूप की आवश्यकता है .. क्योंकि मेरे पास क्लिपबोर्ड से कोई कॉलबैक ईवेंट नहीं है। –

1

अजगर 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% समान है जो पहले पोस्ट किया गया है, केवल अंतर ही पायथन 3 शैली 'प्रिंट()' है, वास्तव में एक अलग उत्तर के लायक नहीं है – jps