這篇可能是你見過最全的滑鼠鍵盤監測

Python_xiaohe發表於2020-03-22
import time
from  pynput.mouse import Button
from pynput.keyboard import Controller, Key
from pynput.keyboard import Listener as Keyboard_Listener
from pynput.mouse import Listener as Mouse_Listener
import os
from threading import Thread

#用於區分單雙擊
click_location=[]
time_difference=0
click_count=1
click_time=[]
path_clicked={}

#用於存放監聽命令
##global command_list
command_list=[]

#表頭為輸入函式庫
title ='\n'+ 'import pyautogui'+'\n' + 'import time' + '\n' +'\n'

def on_click(x, y , button, pressed):

    if pressed:  #點選時為ture  如果不進行判斷會呼叫兩次這個函式 一次點選一次釋放 這裡不需要兩次
        global click_count
        global time_difference  #把時間差設為全域性變數 為的是退出這個迴圈


        t=time.time()   #獲取當前電腦時間
        click_time.append(t) #新增時間
        click_location.append((x,y)) #新增位置

        if len(click_location)!=1:  #這幾個判斷以及上面定義的click_ 都是為了得到雙擊還是單擊  兩個list長度都是2 第一個和第二個比較時間差
            time_difference=click_time[1]-click_time[0]  #定義時間差

            if click_location[0]==click_location[1]:
                if time_difference<=0.3:  #如果兩次點選時間小於0.3秒就會判斷為雙擊 否則就是單擊
                    click_count=2
                else:
                    click_count=1
            else:
                click_count=1
            click_time.pop(0)  #刪去第一個
            click_location.pop(0)

        if button == Button.left:  #判斷左鍵還是右鍵還是中鍵
            button_name = 'Button_left'
        elif button == Button.middle:
            button_name = 'Button_middle'
        elif button == Button.right:
            button_name = 'Button_right'
        else:
            button_name = 'Unknown'

        if 'Key.esc' in all_key:
            #在按下esc時將不再監控滑鼠
            return False
        else:

            if button_name == 'Button_left' and click_count == 1:
                command = 'pyautogui.click{0}'.format((x,y))+'\n' + 'time.sleep(' + str(round(time_difference,2)) + ')' +'\n'
                command_list.append(command)

            elif button_name == 'Button_left' and click_count== 2:
                command = 'pyautogui.doubleClick{0}'.format((x,y)) +'\n'+ 'time.sleep(' + str(round(time_difference,2)) + ')' +'\n'
                command_list.pop(-1)
                command_list.append(command)

            elif button_name == 'Button_right' and click_count == 1:
                command = 'pyautogui.rightClick{0}'.format((x,y))+'\n'+ 'time.sleep(' + str(round(time_difference,2)) + ')' +'\n'
                command_list.append(command)
            elif button_name == 'Button_middle' and click_count == 1:
                command = 'pyautogui.click(button= \'middle\')'+'\n'+ 'time.sleep(' + str(round(time_difference,2)) + ')' +'\n'
                command_list.append(command)

def on_scroll(x, y, dx, dy):
    # 監聽滑鼠滾輪
    if 'Key.esc' in all_key:
    #在按下esc時將不再監控滑鼠
        return False
    else:
        command = 'pyautogui.scroll({0})'.format(dy*120) + '\n' #滾輪滾一下值為120
        command_list.append(command)
        print('pyautogui.scroll({0})'.format(dy*120))

def on_release(key):

    all_key.append(str(key)) #用於在滑鼠事件中監控是否按下esc

    if len(str(key))>3:     #用於區分按了字母鍵和功能鍵
        keyword = '\'' + str(key)[4:] + '\''
    else:
        keyword = str(key)
    command = keyword + '\n'#輸出autogui可用語句


    if key == Key.esc:  #當按下esc停止監控
        return False
    else:
        command_list.append(command)
        print(command_list)

def text_create(name, msg):

    desktop_path = os.path.abspath('.')  # 新建立的txt檔案的存放路徑
    full_path = desktop_path + '\\' + name + '~' + '.txt'
    file = open(full_path, 'a')
    file.write(msg)  
    file.close

def clear_txt(name):    #清空內容

    desktop_path = os.path.abspath('.')  # 新建立的txt檔案的存放路徑
    full_path = desktop_path + '\\' + name + '.txt'

    global distinguish_py   #主程式會用到
    distinguish_py = desktop_path + '\\' + name + '.py'

    if os.path.exists(full_path):
        file = open(full_path, 'r+')
        file.truncate()
        file.close

def hot_key(name):  #主要作用就是將組合鍵從單擊字元形式轉成hot_key模式
    desktop_path = os.path.abspath('.')  # 新建立的txt檔案的存放路徑
    global full_path
    full_path = desktop_path + '\\' + name +'~'+ '.txt' #過渡檔案
    replace_path = desktop_path + '\\' + name + '.txt'  #最終檔案

    b = open(replace_path, 'a')
    f = open(full_path, 'r+')

    line = f.readline()
    hotkey_list = []

    func_key_list = ['ctrl', 'alt' , 'shift','cmd']   #功能按鍵
    while line:
        line = f.readline() #多讀了一行,剛好把原來空行過掉

        if line[:1]=='\'':  #識別字母按鍵
            for func_key in func_key_list:  
                if func_key in hotkey_list and func_key not in line: #當前一個為功能按鍵,後一個可能還是功能鍵可以也是字母鍵,此處只要字母鍵
                    command = 'pyautogui.hotkey(\'' + func_key  + '\''+ ','+ line.strip() + ')' +'\n'
                    b.write(command)  
                    hotkey_list = []    #清空為識別下一對組合按鍵,預設所有組合按鍵為兩個按鍵

                if func_key in line:    #識別第一個功能按鍵
                    hotkey_list.append(func_key)
        else:
            b.write(line)      

    b.close
    f.close

def change_suffix(name):
    desktop_path = os.path.abspath('.')  # 新建立的txt檔案的存放路徑
    full_path = desktop_path + '\\' + name + '.txt'
    portion = os.path.splitext(full_path)
    if portion[1] == '.txt':
        # 重新組合檔名和字尾名
        newname = portion[0] + '.py'
        os.rename(full_path, newname)


#################################################################################################################################
def mouse_click(x, y):
    pass
def mouse_dclick(x, y):
    pass

def mouse_drag():
    (x1,y1)= on_click(x,y)
    (x2,y2)= on_dclick(x, y)
    if (x1y1) != (x2,y2):
        command = 'pyautogui.click(941,34, button=\'left\')' + '\n' + 'pyautogui.dragRel(0,100, button=\'left\', duration=5)'
        command_list.append(command)
        print(command)

    #功能待開發
    #pyautogui.dragTo(x=427, y=535, duration=3,button='left')

#################################################################################################################################
if __name__=='__main__':

    num = 0     #命名時用到
    #最小化所有視窗待開發
    export_file = 'record'  #預設檔名
    clear_txt(export_file)      #清空txt

    while os.path.isfile(distinguish_py):
        num=int(num)+1
        export_file = 'record'+ '(' + str(num) +')'
        distinguish_py = os.path.abspath('.') + '\\' + export_file + '.py'#用於命名(1)

    text_create(export_file, title)    #先把引入函式寫進去,此處title多留一行空白為後面生成最終檔案用

    global all_key  #獲取按鍵資訊
    all_key = []

    global keyboard_listen_thread   #分執行緒,兩事件同時進行
    global mouse_listen_thread

    # 滑鼠單獨執行緒
    mouse_listen_thread = Mouse_Listener(on_click=on_click, on_scroll=on_scroll)
    mouse_listen_thread.start()

    # 鍵盤單獨執行緒
    keyboard_listen_thread = Keyboard_Listener(on_release=on_release)
    keyboard_listen_thread.start()

    keyboard_listen_thread.join()   #當按鍵程式結束後,滑鼠程式也隨之結束,後面才繼續執行

    for command in command_list:

        text_create(export_file, command)   #寫入txt檔案

    hot_key(export_file)        #此步驟為把熱鍵整合
    change_suffix(export_file)  #更改字尾名
    os.remove(full_path)        #刪除過渡檔案.txt

    print("All commands have been recorded!")
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章