吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 330|回复: 6
收起左侧

[其他求助] python问题:按键无限循环

[复制链接]
17612032645 发表于 2024-3-31 18:58
50吾爱币
作为一名python新手,突发奇想想到能不能用python实现急停功能,于是我就自己写了一个,但是出现了问题,请路过大佬指点以下,谢谢
以下是代码

import ctypes
import keyboard
import threading

kmdll = ctypes.CDLL(r'./ddll64.dll')

ret = kmdll.OpenDeviceByID(0, 0)
if not ret:
    print("unlink")
else:
    kmdll.EnableAccurateDelay()
    print("xing hao:", kmdll.GetModel())
    print("ban ben:", kmdll.DllGetVersion())
    print("ID:", kmdll.GetChipID())

kmdll.Notify_KeyBoard(1)

def on_key_release_a(event=None):
    kmdll.KeyPressVirtualCode(68, 50, 120)

def on_key_release_d(event=None):
    kmdll.KeyPressVirtualCode(65, 50, 120)

def on_key_release_w(event=None):
    kmdll.KeyPressVirtualCode(83, 50, 120)

thread_a = threading.Thread(target=keyboard.on_release_key, args=('a', on_key_release_a))
thread_d = threading.Thread(target=keyboard.on_release_key, args=('d', on_key_release_d))
thread_w = threading.Thread(target=keyboard.on_release_key, args=('w', on_key_release_w))

thread_a.start()
thread_d.start()
thread_w.start()

thread_a.join()
thread_d.join()
thread_w.join()

keyboard.wait()

kmdll.Close()


问题在A键和D键无限循环按下弹起,我想实现的功能是当A键松开时只按一下D键,反之亦然。
一开始我是三个功能整合在一个线程里,发现无限循环,后来分成三个线程加了线程锁也还是无限循环,用条件锁功能就实现不了
后面我还需要用nuitka打包成exe
请各位大佬给点解决思路,如果有例子就更好了
python新手,请给位大佬多多指点

最佳答案

查看完整内容

那加多个变量,不给它循环呗 [mw_shl_code=python,true] import pyautogui from pynput import keyboard block_sign = 1 # 按下按键方法 def on_press(key): pass # 松开按键方法 def on_release(key): global block_sign # try: if key.char == 'a': if block_sign == 1: # 按一次按键 d pyautogui.press('d') ...

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

demonw 发表于 2024-3-31 18:58
17612032645 发表于 2024-4-1 09:58
你这里只有监听到按键a松开按一次按键 d,如果加上监听到按键d松开按一次按键 a,就会陷入a键d键无限循环 ...

那加多个变量,不给它循环呗
[Python] 纯文本查看 复制代码
import pyautogui
from pynput import keyboard

block_sign = 1

# 按下按键方法
def on_press(key):
    pass

# 松开按键方法
def on_release(key):
    global block_sign
    # 
    try:
        if key.char == 'a':
            if  block_sign == 1:
                # 按一次按键 d
                pyautogui.press('d')
                f = 0
            else:
                block_sign = 1

        if key.char == 'd':
            if block_sign == 1:
                # 按一次按键 a
                pyautogui.press('a')
                block_sign = 0
            else:
                block_sign = 1
    except AttributeError:
        print(key)


    # 检测到按键 esc , 结束监听
    if key == keyboard.Key.esc:
        return False

#绑定事件及监听
with keyboard.Listener(
    on_release = on_release,
    on_press = on_press
) as pklistener:
    pklistener.join()
LaoShui08 发表于 2024-3-31 23:38

这似乎是用在游戏里的?从代码来看,通过监听键盘 a、d 和 w 键的释放事件来模拟按下对应的其他键(D对应A,A对应D,W对应S)。但是,每次释放键都会触发一次模拟按下事件,这会导致实际上形成了两个键之间的连续交替按下,形成“无限循环”

要实现当 A 键松开时只按一下 D 键,反之亦然,你需要追踪按键的状态,并且只在状态改变时执行一次模拟操作。这里的关键是添加一个标志变量来记录上一次被释放的键,并判断当前释放的键是否与上次不同

因为不太了解需求 给一个例子

import ctypes
import keyboard
import threading

kmdll = ctypes.CDLL(r'./ddll64.dll')

last_released_key = None

def on_key_release(event):
    global last_released_key

    if event.name == 'a':
        # 如果上次不是 A 键释放,则模拟按 D 键
        if last_released_key != 'a':
            kmdll.KeyPressVirtualCode(65, 50, 120)  # 注意此处应是模拟 D 键,而非 A 键
        last_released_key = 'a'
    elif event.name == 'd':
        if last_released_key != 'd':
            kmdll.KeyPressVirtualCode(68, 50, 120)  # 模拟 A 键
        last_released_key = 'd'

keyboard.on_release(on_key_release)

# ... 其他线程逻辑不再需要,因为现在只有一个统一的释放事件处理函数 ...

keyboard.wait()

kmdll.Close()

使用一个全局变量 last_released_key 记录上次释放的是哪个键,这样就能避免在短时间内连续触发多次相同动作?

demonw 发表于 2024-4-1 09:42
自行安装pyautogui,pynput 这两个库
[Python] 纯文本查看 复制代码
import pyautogui
from pynput import keyboard

# 按下按键方法
def on_press(key):
    pass

# 松开按键方法
def on_release(key):
    # 监听到按键a松开
    if key.char == 'a':
        # 按一次按键 d
        pyautogui.press('d')

    # 检测到按键 esc , 结束监听
    if key == keyboard.Key.esc:
        return False

#绑定事件及监听
with keyboard.Listener(
    on_release = on_release,
    on_press = on_press
) as pklistener:
    pklistener.join()
 楼主| 17612032645 发表于 2024-4-1 09:58
demonw 发表于 2024-4-1 09:42
自行安装pyautogui,pynput 这两个库
[mw_shl_code=python,true]
import pyautogui

你这里只有监听到按键a松开按一次按键 d,如果加上监听到按键d松开按一次按键 a,就会陷入a键d键无限循环

我有硬件,所以我的代码是调用硬件的dll来模拟键盘输入的,写法可能和普通python不一样
 楼主| 17612032645 发表于 2024-4-1 10:17
LaoShui08 发表于 2024-3-31 23:38
[md]这似乎是用在游戏里的?从代码来看,通过监听键盘 a、d 和 w 键的释放事件来模拟按下对应的其他键(D对 ...

我的需求是,“当A键松开时按下D键”和“当D键松开时按下A键”及“当W键松开时按下S键”,从而实现游戏中,大家所说的“急停”,大佬你的代码里,如果按其他按键(比如W或S)也会触发模拟按下A键和D键吧
 楼主| 17612032645 发表于 2024-4-1 17:23
demonw 发表于 2024-4-1 13:29
那加多个变量,不给它循环呗
[Python] 纯文本查看 复制代码
import pyautogui
[/quote]

感谢大佬提供思路,我按照你的思路修改了以下可以实现功能了,最开始我也试过加个虚拟按键监测的全局变量限制,可能写法出现问题问题没实现。非常感谢

[mw_shl_code=python,true]def on_key_release_a(event=None):
    global block_sign
    
    if block_sign == 1:
        delay = random.uniform(0.02, 0.03)
        time.sleep(delay)  
        kmdll.KeyPressCode(7, 50, 80)
        block_sign = 0
    else:
         block_sign = 1

def on_key_release_d(event=None):
    global block_sign
    
    if block_sign == 1:
        delay = random.uniform(0.02, 0.03)
        time.sleep(delay)
        kmdll.KeyPressCode(4, 50, 80)
        block_sign = 0
    else:
        block_sign = 1
    
def on_key_release_w(event=None):
      delay = random.uniform(0.02, 0.03)
      time.sleep(delay)
      kmdll.KeyPressCode(22, 50, 80)
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-14 13:22

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表