PyQt5开发精确测试鼠标DPI的功能


前文:本文赠给正在开发如何精确测试鼠标DPI功能的码友

(一)术语简介


1.鼠标DPI介绍:


鼠标 DPI(Dots Per Inch,每英寸点数)是衡量鼠标精度的一个指标。
一般来说,如果已知鼠标移动的物理距离(通常以英寸为单位)和鼠标指针在屏幕上移动的像素距离,可以通过以下公式计算鼠标 DPI:
DPI = (像素距离 / 物理距离mm) * 25.4(因为 1 英寸等于 25.4 毫米)。
例如,鼠标在平面上移动了 2mm,屏幕上的鼠标指针移动了 800 像素,那么 DPI = (800 / 2) * 25.4 = 10160。
需要注意的是,不同的鼠标可能有不同的测量方法和精度,并且一些鼠标可以通过软件调整 DPI 设置。
此外,上述计算假设鼠标的移动是完全直线的(当然斜线可以采用勾股定理计算),实际情况可能会更加复杂。

2.单位换算:


1毫米=0.0393701英寸
1厘米=0.3937008英寸

(二)专业设备


1.奎享雕刻写字机器人


项目采用串口发送指令的方式向写字机中发送执行指令,以获取精确的移动距离


2.相关的数控G指令代码:


(1)定原点
G10 P0 L20 X0.000Y0.000Z0.000F1000\rG21\rG90\rF1000\rG1G90 Z0.0F1000\r
(2)来回画直线
G1 X30.000Y0.000F800\rG1 X0.00Y0.000F800\r
(3)循环画圆(半径设为1mm, 周长可以自己计算从而得出移动速度即指令的执行周期)
G2 X1.000Y1.000R1.000F800\rG2 X2.000Y0.000R1.000F800\rG2 X1.000Y-1.000R1.000F800\rG2 X0.000Y0.000R1.000F800\r


3.特殊字符规避

注意G指令发送时是否会受\r等特殊字符的影响,特殊字符如下需自己代码规避


\f  0x0c  换页符
\a  0x07  响铃符
\b  0x08  退格符
\t  0x09  水平制表符
\n  0x0a  换行键
\v  0x0b  垂直制表符
\r  0x0d  回车键

4.下面是我写的一个多线程

class LoopDpiSendCmdThread(QtCore.QThread):
    cmd_sig = QtCore.pyqtSignal(str)  # 命令发送信号
    clear_info_sig = QtCore.pyqtSignal()  # 清空日志信号
    stop_thread = QtCore.pyqtSignal()  # 停止线程信号
    init_cmd = QtCore.pyqtSignal()  # 首次命令信号
    point_sig = QtCore.pyqtSignal()  # 点坐标信号

    def __init__(self, loop_data_dict, serial_object):
        super().__init__()
        self.loop_data_dict = loop_data_dict
        self.serial_object = serial_object
        self.interval_task = self.send_interval = None

    def run(self):
        """异步执行的主线程"""
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        task = [self.start_loop_send_cmd_worker(self.loop_data_dict)]
        # 根据输入数据创建多任务数
        loop.run_until_complete(asyncio.gather(*task))

    async def start_loop_send_cmd_worker(self, data_dict):
        """启动同步线程: 多任务并行执行"""
        loop_times = data_dict.get("loop_times")
        cmd_list = data_dict.get("func_cmd").split("\r")[:-1]
        # 1.定点命令发送
        self.cmd_sig.emit(data_dict.get("origin_cmd"))
        # 等待串口返回结果响应完成(该步骤会阻塞主线程, 故放在子线程中)
        self.serial_object.waitForReadyRead(100)
        # 首次命令发送完成
        self.init_cmd.emit()

        loop_count = 0
        while True:
            # 统计循环次数
            loop_count += 1
            # awaken_times为0表示持续进行唤醒操作, 不为0表示唤醒指定次数后退出唤醒
            if loop_times == 0:
                if loop_count >= 1000:
                    self.clear_info_sig.emit()
                    loop_count = 0
            else:
                if loop_count > loop_times:
                    self.stop_thread.emit()
                    break
            try:
                # 发送指令
                for cmd_str in cmd_list:
                    # 触发信号, 发送命令信息
                    self.cmd_sig.emit(cmd_str)
                    # 等待串口返回结果响应完成(该步骤会阻塞主线程, 故放在子线程中)
                    self.serial_object.waitForReadyRead(50)
                    # GPIO指令的延时
                    await asyncio.sleep(data_dict.get("send_interval"))
                    if data_dict.get("dpi_delay"):
                        self.point_sig.emit()
            except Exception as e:
                print(e)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值