Windows系统环境下Python脚本实现全局“划词复制”功能

  1 from pynput import mouse
  2 import time
  3 import threading
  4 
  5 __DEBUG = False
  6 
  7 def log(msg,debug=False):
  8     if __DEBUG or debug:
  9         print(msg)
 10 
 11 class MouseMonitor():
 12     __press_time = 0
 13     __press_double_state = False
 14     __move = (0,0)
 15 
 16     def __init__(self,on_selected=None):
 17         if on_selected:
 18             self.on_selected = on_selected
 19         else:
 20             self.on_selected = self.on_selected
 21 
 22         self.listener = mouse.Listener(on_move=self.on_move,on_click=self.on_click)
 23         self.listener.start()
 24         self.listener.join()
 25 
 26     def on_selected(msg):
 27         print('selected "%s" has been copied.' % (msg,))
 28 
 29     def on_move(self,x,y):
 30         if self.__press_time == 0:
 31             self.__move = (x,y)
 32         # log(self.__press_time,time.time())
 33         # log('Pointer moved to {0}'.format((x,y)))
 34 
 35     def on_click(self,x,y,button,pressed):
 36         if str(button) == 'Button.left':
 37             if pressed:
 38                 self.on_pressed(x,y)
 39             else:
 40                 self.on_released(x,y)
 41 
 42     def on_pressed(self,x,y):
 43         if self.__press_double_state:
 44             # double click
 45             # self.__press_double_state = False
 46             if not self.check_not_time_out(self.__press_time, time.time(),0.4): # miss double click
 47                 log('double1 click timeout and reset then')
 48                 self.reset()
 49                 self.__press_time = time.time()
 50         else:
 51             # single click
 52             self.__press_time = time.time()
 53             # self.__press_double_state = False
 54 
 55     def on_released(self,x,y):
 56         if self.__press_double_state:
 57             # double click
 58             if self.check_not_time_out(self.__press_time, time.time(),0.8):
 59                 log('double click: %s' % (self.get_copy()))
 60                 self.on_selected(self.get_copy())
 61                 self.__press_double_state = False
 62             else:
 63                 log('double2 click timeout and reset then')
 64                 self.reset()
 65         else:
 66             if self.check_not_time_out(self.__press_time, time.time()):
 67                 log('double click maybe')
 68                 self.__press_double_state = True
 69                 threading.Timer(0.5, self.timeout_handler).start() # wait timeout to reset
 70             elif not self.check_not_time_out(self.__press_time, time.time(),1):
 71                 if self.__move != (0,0):
 72                     self.on_selected(self.get_copy())
 73                     log('selected: %s' % (self.get_copy(),))
 74                     self.reset()
 75             else:
 76                 log('reset state')
 77                 self.reset()
 78 
 79     def get_copy(self):
 80         import win32clipboard as wc
 81         import win32con
 82 
 83         def trigger_copy():
 84             from pynput.keyboard import Key,Controller
 85             key = Controller()
 86             with key.pressed(Key.ctrl):
 87                 key.press('c')
 88                 key.release('c')
 89             time.sleep(0.1) # wait for ctrl+c valid
 90 
 91         trigger_copy()
 92         msg = ''
 93         try:
 94             wc.OpenClipboard()
 95             msg = wc.GetClipboardData(win32con.CF_UNICODETEXT)
 96             wc.CloseClipboard()
 97         except TypeError:
 98             log('Clipboard Content is TypeError.')
 99         return msg
100 
101     def reset(self):
102         self.__press_time = 0
103         self.__press_double_state = False
104         self.__move = (0,0)
105 
106     def timeout_handler(self):
107         self.reset()
108         log('timeout reset state')
109 
110     def check_not_time_out(self,old,new,delta=0.2):
111         if(new - old > delta): # time delta > 0.2s
112             return False
113         else:
114             return True
115 
116 
117 def printf(msg):
118     log('copy content:'+msg,True)
119     # log('x = {0} , y = {1}'.format(x,y))
120 
121 
122 if __name__ == '__main__':
123     mm = MouseMonitor(printf)

 

posted @ 2019-07-22 17:28  缘起花渊  阅读(833)  评论(0编辑  收藏  举报