利用Python統(tǒng)計每天敲了多少次鍵盤
分析
語言用python,實現(xiàn)方式那必然是要監(jiān)聽鍵盤的輸入信號,然后對每個按鍵做統(tǒng)計,最后顯示結(jié)果。
核心代碼
查閱一下,python中有一個pynput庫是專門用來做鍵盤、鼠標操作相關(guān)的,可以對事件進行監(jiān)聽,同時還可以模擬鍵盤、鼠標進行操作(感覺這個功能很強大,順帶成為了我后續(xù)的一個項目的解決方案)。
pip install pynput
直接裝就行,示例代碼如下:
from pynput.keyboard import Listener
def on_press(key):
pass
def on_release(key):
pass
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
很直觀,自己實現(xiàn)一個on_press和on_release的方法賦給Listener對象,啟動現(xiàn)成監(jiān)聽即可。其中,on_press和on_release分別代表按下和釋放時的相應操作,傳入的key類型為pynput內(nèi)定的Key類,具體細節(jié)大家可以看源代碼。
按鍵統(tǒng)計
有了核心代碼之后,剩下的就是在這個基礎上進行功能擴展了,先實現(xiàn)統(tǒng)計功能
from pynput.keyboard import Listener
# 單個按鍵次數(shù)
key_counts = {}
# key格式化函數(shù)
def format_key(key):
if hasattr(key, 'name'):
return key.name
elif hasattr(key, 'vk'):
if 65 <= key.vk <= 127:
return chr(key.vk)
else:
return str(key.char)
def on_press(key):
current_key.add(key_id)
print(key_id)
if key_counts.get(key_id):
key_counts[key_id] += 1
else:
key_counts[key_id] = 1
def on_release(key):
pass
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
這里我除了引入一個key_counts來計數(shù)之外,還專門寫了一個key格式化的函數(shù),因為如果debug的話就會發(fā)現(xiàn),除了標準的可見字符之外,當輸入類似Ctrl+A這種實際傳入的是一個不可見的控制字符的十六進制編碼,這里將類似的字符做了一層轉(zhuǎn)換。
現(xiàn)在整個雛形就搞定了。
設定組合鍵
這個程序是要后臺運行的,那么就要考慮兩點,程序怎么退出?我怎么看到按鍵的統(tǒng)計?
于是乎就需要設定組合鍵來做一些操作。
from pynput.keyboard import Listener
import time
from ui.TextDialog import create_window_with_text
# 單個按鍵次數(shù)
key_counts = {}
exit_cmd = {'alt_l', 'ctrl_l', 'shift', 'A'}
show_cmd = {'alt_l', 'ctrl_l', 'shift', 'space'}
current_key = set()
def format_key(key):
if hasattr(key, 'name'):
return key.name
elif hasattr(key, 'vk'):
if 65 <= key.vk <= 127:
return chr(key.vk)
else:
return str(key.char)
def get_result():
pass
def cmd_parse():
if exit_cmd.issubset(current_key):
get_result()
return False
if show_cmd.issubset(current_key):
get_result()
return True
def on_press(key):
key_id = format_key(key)
current_key.add(key_id)
print(key_id)
if key_counts.get(key_id):
key_counts[key_id] += 1
else:
key_counts[key_id] = 1
if not cmd_parse():
return False
def on_release(key):
try:
key_id = format_key(key)
current_key.remove(key_id)
except KeyError:
pass
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
根據(jù)代碼,我新增了組合鍵的功能,同時引入了current_key作為集合變量,來存儲當前按住的按鍵。
- Ctrl+Shift+Alt+空格:顯示統(tǒng)計結(jié)果
- Ctrl+Shift+Alt+A:顯示統(tǒng)計結(jié)果并退出
值得一提的是,鍵盤on_press或者on_release方法默認是沒有返回值的,如果返回False,則就會退出線程,進而結(jié)束程序。
那么如此一來,基礎功能就有了,咱們再補充上get_result()這個用來顯示統(tǒng)計結(jié)果的函數(shù)。
...
start_time = time.time()
def time_counter(begin_time, end_time):
# 根據(jù)傳入的時間計算,通過run_time.round()函數(shù)取整
runtime = round(end_time - begin_time)
# 計算時分秒
hour = runtime // 3600
minute = (runtime - 3600 * hour) // 60
second = runtime - 3600 * hour - 60 * minute
# 輸出
return f'程序運行\(zhòng)n{hour}小時 {minute}分鐘 {second}秒\n'
def get_result():
end_time = time.time()
counts = dict(sorted(key_counts.items(), key=lambda item: item[1], reverse=True))
content = ""
count = 0
col = 0
for k, v in counts.items():
col += 1
content += f"{k}: {v}\t"
count += v
if col == 4:
col = 0
content += "\n"
current_key.clear()
try:
max_key = list(counts.keys())[0]
except:
max_key = None
fixed = "\n" + time_counter(start_time, end_time) + f"\n你總共敲了 {count} 下鍵盤\n\n最多使用\n{max_key}"
print(fixed)
print(counts)
...
很簡單就是打印一下

UI界面
控制臺打印肯定不行,太low了而且還看的不直觀,于是讓ChatGPT簡單用tkinter搞了個界面,實際效果如下:

代碼如下:
import tkinter as tk
from tkinter import ttk
def create_window_with_text(title, fixed_text, data):
window = tk.Tk()
window.title(title)
# 設置窗口初始大小和在屏幕上居中顯示
window_width = 400
window_height = 200
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
center_x = int(screen_width / 2 - window_width / 2)
center_y = int(screen_height / 2 - window_height / 2)
window.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
# 創(chuàng)建PanedWindow,分為左右兩塊
paned_window = tk.PanedWindow(window, orient=tk.HORIZONTAL)
paned_window.pack(fill=tk.BOTH, expand=1)
# 左邊的面板,設置較大的字體
left_panel = tk.Frame(paned_window, width=100, height=400, bg='white')
left_panel.pack_propagate(False)
label = tk.Label(left_panel, text=fixed_text, bg='white', font=("Arial", 12))
label.pack(side=tk.TOP, fill=tk.BOTH, padx=20) # padx為文本增加左側(cè)內(nèi)邊距
paned_window.add(left_panel, stretch="always")
# 右邊的面板,使用Treeview作為可拖拽的列表
right_panel = tk.Frame(paned_window, width=100, height=400)
right_panel.pack_propagate(False)
tree = ttk.Treeview(right_panel, columns=('Key', 'Count'), show='headings')
tree.heading('Key', text='按鍵')
tree.heading('Count', text='次數(shù)')
tree.column('Key', width=60) # 調(diào)整列的寬度
tree.column('Count', width=30)
tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
scrollbar = ttk.Scrollbar(right_panel, orient='vertical', command=tree.yview)
tree.configure(yscroll=scrollbar.set)
scrollbar.pack(side=tk.RIGHT, fill='y')
# 將數(shù)據(jù)添加到Treeview
for key, count in data.items():
tree.insert('', 'end', values=(key, count))
paned_window.add(right_panel, stretch="always")
# 窗口保持在最前面
window.attributes('-topmost', True)
# 啟動事件循環(huán)
window.mainloop()
直接將get_result()函數(shù)中print()的部分調(diào)用該函數(shù)傳入?yún)?shù)即可。
以上就是利用Python統(tǒng)計每天敲了多少次鍵盤的詳細內(nèi)容,更多關(guān)于Python鍵盤的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pytest使用fixture實現(xiàn)token共享的方法
同學們在做pytest接口自動化時,會遇到一個場景就是不同的測試用例需要有一個登錄的前置步驟,登錄完成后會獲取到token,用于之后的代碼中,本文給大家介紹Pytest使用fixture實現(xiàn)token共享的方法,感興趣的朋友一起看看吧2023-11-11
一文帶你掌握Python內(nèi)置reversed函數(shù)的使用
Python作為一門強大的編程語言,提供了許多內(nèi)置函數(shù)來處理各種數(shù)據(jù)結(jié)構(gòu)和對象,本文將詳細探討reversed函數(shù)的用法、示例代碼以及實際應用場景,需要的可以參考下2024-01-01
django執(zhí)行原始查詢sql,并返回Dict字典例子
這篇文章主要介紹了django執(zhí)行原始查詢sql,并返回Dict字典例子,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
python使用wmi模塊獲取windows下的系統(tǒng)信息 監(jiān)控系統(tǒng)
Python用WMI模塊獲取Windows系統(tǒng)的硬件信息:硬盤分區(qū)、使用情況,內(nèi)存大小,CPU型號,當前運行的進程,自啟動程序及位置,系統(tǒng)的版本等信息。2015-10-10

