利用Python统计每天敲了多少次键盘

 更新时间:2024年04月17日 08:34:57   作者:银空飞羽  
每到年末各大App都会给你来一次年度总结,最近突发奇想,键盘是每天必备的工具,为啥不给键盘也来个工作总结,本文就来用Python统计一下每天敲了多少次键盘吧

分析

语言用python,实现方式那必然是要监听键盘的输入信号,然后对每个按键做统计,最后显示结果。

核心代码

查阅一下,python中有一个pynput库是专门用来做键盘、鼠标操作相关的,可以对事件进行监听,同时还可以模拟键盘、鼠标进行操作(感觉这个功能很强大,顺带成为了我后续的一个项目的解决方案)。

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()

很直观,自己实现一个on_press和on_release的方法赋给Listener对象,启动现成监听即可。其中,on_press和on_release分别代表按下和释放时的相应操作,传入的key类型为pynput内定的Key类,具体细节大家可以看源代码。

按键统计

有了核心代码之后,剩下的就是在这个基础上进行功能扩展了,先实现统计功能

from pynput.keyboard import Listener

# 单个按键次数
key_counts = {}

# key格式化函数
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来计数之外,还专门写了一个key格式化的函数,因为如果debug的话就会发现,除了标准的可见字符之外,当输入类似Ctrl+A这种实际传入的是一个不可见的控制字符的十六进制编码,这里将类似的字符做了一层转换。

现在整个雏形就搞定了。

设定组合键

这个程序是要后台运行的,那么就要考虑两点,程序怎么退出?我怎么看到按键的统计?

于是乎就需要设定组合键来做一些操作。

from pynput.keyboard import Listener
import time

from ui.TextDialog import create_window_with_text


# 单个按键次数
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()

根据代码,我新增了组合键的功能,同时引入了current_key作为集合变量,来存储当前按住的按键。

  • Ctrl+Shift+Alt+空格:显示统计结果
  • Ctrl+Shift+Alt+A:显示统计结果并退出

值得一提的是,键盘on_press或者on_release方法默认是没有返回值的,如果返回False,则就会退出线程,进而结束程序。

那么如此一来,基础功能就有了,咱们再补充上get_result()这个用来显示统计结果的函数。

...
start_time = time.time()


def time_counter(begin_time, end_time):
    # 根据传入的时间计算,通过run_time.round()函数取整
    runtime = round(end_time - begin_time)
    # 计算时分秒
    hour = runtime // 3600
    minute = (runtime - 3600 * hour) // 60
    second = runtime - 3600 * hour - 60 * minute
    # 输出
    return f'程序运行\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}')

    # 创建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为文本增加左侧内边距
    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='次数')
    tree.column('Key', width=60)  # 调整列的宽度
    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')

    # 将数据添加到Treeview
    for key, count in data.items():
        tree.insert('', 'end', values=(key, count))

    paned_window.add(right_panel, stretch="always")

    # 窗口保持在最前面
    window.attributes('-topmost', True)

    # 启动事件循环
    window.mainloop()

直接将get_result()函数中print()的部分调用该函数传入参数即可。

以上就是利用Python统计每天敲了多少次键盘的详细内容,更多关于Python键盘的资料请关注脚本之家其它相关文章!

相关文章

  • Pytest使用fixture实现token共享的方法

    Pytest使用fixture实现token共享的方法

    同学们在做pytest接口自动化时,会遇到一个场景就是不同的测试用例需要有一个登录的前置步骤,登录完成后会获取到token,用于之后的代码中,本文给大家介绍Pytest使用fixture实现token共享的方法,感兴趣的朋友一起看看吧
    2023-11-11
  • python百行代码实现汉服圈图片爬取

    python百行代码实现汉服圈图片爬取

    这篇文章主要为大家介绍了使用python百行代码来实现汉服圈的图片爬取,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • Python中求对数方法总结

    Python中求对数方法总结

    这篇文章主要介绍了Python中求对数方法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • flask框架实现修改密码和免密登录功能

    flask框架实现修改密码和免密登录功能

    flask是python web开发的常用框架之一。本文将讲述flask如何实现修改密码和免密登录功能
    2021-05-05
  • Mac中升级Python2.7到Python3.5步骤详解

    Mac中升级Python2.7到Python3.5步骤详解

    本篇文章主要介绍了Mac中升级Python2.7到Python3.5步骤详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-04-04
  • django页面跳转问题及注意事项

    django页面跳转问题及注意事项

    这篇文章主要介绍了django页面跳转问题及注意事项,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • 一文带你掌握Python内置reversed函数的使用

    一文带你掌握Python内置reversed函数的使用

    Python作为一门强大的编程语言,提供了许多内置函数来处理各种数据结构和对象,本文将详细探讨reversed函数的用法、示例代码以及实际应用场景,需要的可以参考下
    2024-01-01
  • Python Numpy中数组的集合操作详解

    Python Numpy中数组的集合操作详解

    这篇文章主要为大家详细介绍了Python Numpy中数组的一些集合操作方法,文中的示例代码讲解详细,对我们学习Python有一定帮助,需要的可以参考一下
    2022-08-08
  • django执行原始查询sql,并返回Dict字典例子

    django执行原始查询sql,并返回Dict字典例子

    这篇文章主要介绍了django执行原始查询sql,并返回Dict字典例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • python使用wmi模块获取windows下的系统信息 监控系统

    python使用wmi模块获取windows下的系统信息 监控系统

    Python用WMI模块获取Windows系统的硬件信息:硬盘分区、使用情况,内存大小,CPU型号,当前运行的进程,自启动程序及位置,系统的版本等信息。
    2015-10-10

最新评论