欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python3注冊(cè)全局熱鍵的實(shí)現(xiàn)

 更新時(shí)間:2020年03月22日 11:25:59   作者:晚風(fēng)拂柳顏  
這篇文章主要介紹了python3注冊(cè)全局熱鍵的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

之前用python3做游戲自動(dòng)化腳本,用過(guò)很多東西,然后最終有一套完整的方案。在這里隨便闡述一下核心思路:

游戲輔助的窗體設(shè)計(jì)方面:

不需要pyqt這種大型軟件,寫小工具用自帶的tkinter就行了。當(dāng)然,并不是自己純手敲代碼,是通過(guò)拖拽來(lái)實(shí)現(xiàn)的。怎么,你還不知道tkinter可以界面拖拽生成代碼就行VB一樣?

呵呵,PAGE了解一下。

游戲輔助的應(yīng)用發(fā)布方面:

自然是用pyinstaller打包成32位版的exe發(fā)布了,帶上程序圖標(biāo),版本信息,都不是事兒

 游戲核心模擬方面:

當(dāng)然不是通過(guò)手敲代碼實(shí)現(xiàn)了,而是通過(guò)調(diào)用目前市場(chǎng)上強(qiáng)大的dll插件了。比如com組件如大漠插件、樂(lè)玩插件。或者說(shuō),把易語(yǔ)言的一些模塊編譯成windll來(lái)調(diào)用也行哦

輔助窗體熱鍵注冊(cè)方面:

這些需要用到底層的東西了,用win32的東西實(shí)現(xiàn)的,可以實(shí)現(xiàn)注冊(cè)全局熱鍵。原理是單獨(dú)一個(gè)線程用于檢測(cè)熱鍵按下,然后熱鍵按下后單獨(dú)開(kāi)辟線程執(zhí)行需要的功能。鑒于原生的太難寫,我自己封裝了并且寫了一個(gè)demo。注冊(cè)全局組合鍵和單獨(dú)的熱鍵都是沒(méi)問(wèn)題的。

前面三個(gè)方面仁者見(jiàn)仁了。后面這個(gè)我就貼個(gè)核心源碼吧,免得以后找不到了。

下面貼一段新的代碼:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# File : 簡(jiǎn)單熱鍵.py
# Author: DaShenHan&道長(zhǎng)-----先苦后甜,任憑晚風(fēng)拂柳顏------
# Date : 2020/3/4
 
import win32con
import ctypes
import ctypes.wintypes
from threading import Thread,activeCount, enumerate
from time import sleep,time
 
class Hotkey(Thread):
  user32 = ctypes.windll.user32
  hkey_list = {}
  hkey_flags = {} #按下
  hkey_running = {} #啟停
  _reg_list = {} #待注冊(cè)熱鍵信息
 
  def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注冊(cè)熱鍵,默認(rèn)一個(gè)alt+F9
    return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey)
 
  def get_reginfo(self):
    return self._reg_list
 
  def get_id(self,func):
    self_id = None
    for id in self.get_reginfo():
      if self.get_reginfo()[id]["func"] == func:
        self_id = id
        break
    if self_id:
      self.hkey_running[self_id] = True
    return self_id
 
  def get_running_state(self,self_id):
    if self.hkey_running.get(self_id):
      return self.hkey_running[self_id]
    else:
      return False
 
  def reg(self,key,func,args=None):
    id = int(str(round(time()*10))[-6:])
    fnkey = key[0]
    vkey = key[1]
    info = {
      "fnkey":fnkey,
      "vkey":vkey,
      "func":func,
      "args":args
    }
    self._reg_list[id] = info
    # print(info) #這里待注冊(cè)的信息
    sleep(0.1)
    return id
 
  def fast_reg(self,id,key = (0,win32con.VK_HOME),func = lambda:print('熱鍵注冊(cè)開(kāi)始')):
    if not self.regiskey(None, id, key[0], key[1]):
      print("熱鍵注冊(cè)失敗")
      return None
    self.hkey_list[id] = func
    self.hkey_flags[id] = False
    return id
 
  def callback(self):
    def inner(self = self):
      for flag in self.hkey_flags:
        self.hkey_flags[flag] = False
 
      while True:
        for id, func in self.hkey_list.items():
          if self.hkey_flags[id]:
            args = self._reg_list[id]["args"]
            if args:
              # print(args)  #這里打印傳入給注冊(cè)函數(shù)的參數(shù)
              thread_it(func,*args)
            else:
              thread_it(func)
            self.hkey_flags[id] = False
    return inner
 
  def run(self):
    for id in self._reg_list:
      reg_info = self._reg_list[id]
      fnkey = reg_info["fnkey"]
      vkey = reg_info["vkey"]
      func = reg_info["func"]
      self.fast_reg(id,(fnkey, vkey), func)
 
    fn = self.callback()
    thread_it(fn) # 啟動(dòng)監(jiān)聽(tīng)熱鍵按下線程
 
    try:
      msg = ctypes.wintypes.MSG()
      while True:
        if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
          if msg.message == win32con.WM_HOTKEY:
            if msg.wParam in self.hkey_list:
              self.hkey_flags[msg.wParam] = True
          self.user32.TranslateMessage(ctypes.byref(msg))
          self.user32.DispatchMessageA(ctypes.byref(msg))
    finally:
      for id in self.hkey_list:
        self.user32.UnregisterHotKey(None, id)
 
def thread_it(func, *args):
  t = Thread(target=func, args=args)
  t.setDaemon(True)
  t.start()
 
def jump(func,hotkey):
  self_id = hotkey.get_id(func)
  while hotkey.get_running_state(self_id):
    print(f"{self_id : } 你正在1秒1次的跳動(dòng)")
    sleep(1)
 
def stop_jump(start_id,hotkey):
  hotkey.hkey_running[start_id] = False
  print(f"{start_id} 即將停止")
  sleep(1)
  print(f'當(dāng)前線程列表:{activeCount()}', enumerate())
 
def main():
  hotkey = Hotkey()
  start_id = hotkey.reg(key = (win32con.MOD_ALT,win32con.VK_HOME),func=jump,args=(jump,hotkey)) #alt home鍵 開(kāi)始
  hotkey.reg(key = (0,win32con.VK_END),func=stop_jump,args=(start_id,hotkey)) #alt end鍵 結(jié)束
  hotkey.start() #啟動(dòng)熱鍵主線程
 
  print(f"當(dāng)前總線程數(shù)量:{activeCount()}")
  print('當(dāng)前線程列表:', enumerate())
  print('熱鍵注冊(cè)初始化完畢,嘗試按組合鍵alt+Home 或者單鍵END看效果')
 
if __name__ == '__main__':
  main()

以下是舊的代碼,用起來(lái)比較麻煩。

#!/usr/bin/env python3
# _*_ coding: utf-8 _*_
# File : demo.py
# Author: DaShenHan&道長(zhǎng)-----先苦后甜,任憑晚風(fēng)拂柳顏------
# Date : 2019/6/28
 
import win32con
import ctypes
import ctypes.wintypes
from threading import Thread, Timer, activeCount, enumerate
from time import sleep
h_ids = [i for i in range(2)] # 創(chuàng)建兩個(gè)熱鍵序列
h_keys = {i: False for i in h_ids} # 初始化所有熱鍵序列的標(biāo)志符為False
h_dict = {} # 初始化一個(gè)空的字典,記錄id與func
 
 
class Hotkey(Thread): # 創(chuàng)建一個(gè)Thread的擴(kuò)展類
  user32 = ctypes.windll.user32 # 加載user32.dll
  # global h_ids, h_keys,h_dict
 
  def regiskey(self, hwnd=None, flagid=0, fnkey=win32con.MOD_ALT, vkey=win32con.VK_F9): # 注冊(cè)熱鍵,默認(rèn)一個(gè)alt+F9
    return self.user32.RegisterHotKey(hwnd, flagid, fnkey, vkey)
 
  def callback(self, id, func):
    h_dict[id] = func # 這個(gè)id對(duì)應(yīng)這個(gè)func,沒(méi)有就是新增,有就是修改
 
    def inner():
      for key, value in h_dict.items():
        print(f'總的熱鍵池:{h_ids},當(dāng)前熱鍵序號(hào):{key}, 當(dāng)前熱鍵功能:{value},當(dāng)前熱鍵狀態(tài):{h_keys[h_ids[key]]}')
      while True:
        for key, value in h_dict.items():
          if h_keys[h_ids[key]]:
            thread_it(value) # 另外開(kāi)線程執(zhí)行value
            h_keys[h_ids[key]] = False
    return inner
 
  def run(self):
    # print(self.user32)
    if not self.regiskey(None,h_ids[0],win32con.MOD_ALT,win32con.VK_F9):  # 注冊(cè)快捷鍵alt+F9并判斷是否成功,該熱鍵用于執(zhí)行一次需要執(zhí)行的內(nèi)容。
      print(f"熱鍵注冊(cè)失??! id{h_ids[0]}") # 返回一個(gè)錯(cuò)誤信息
    if not self.regiskey(None,h_ids[1],0,win32con.VK_F10):  # 注冊(cè)快捷鍵F10并判斷是否成功,該熱鍵用于結(jié)束程序,且最好這么結(jié)束,否則影響下一次注冊(cè)熱鍵。
      print(f"熱鍵注冊(cè)失?。?id{h_ids[1]}")
 
    # 以下為檢測(cè)熱鍵是否被按下,并在最后釋放快捷鍵
    try:
      msg = ctypes.wintypes.MSG()
      while True:
        if self.user32.GetMessageA(ctypes.byref(msg), None, 0, 0) != 0:
          if msg.message == win32con.WM_HOTKEY:
            if msg.wParam in h_ids:
              h_keys[msg.wParam] = True
          self.user32.TranslateMessage(ctypes.byref(msg))
          self.user32.DispatchMessageA(ctypes.byref(msg))
    finally:
      for i in h_ids:
        self.user32.UnregisterHotKey(None, i)
        # 必須得釋放熱鍵,否則下次就會(huì)注冊(cè)失敗,所以當(dāng)程序異常退出,沒(méi)有釋放熱鍵,
        # 那么下次很可能就沒(méi)辦法注冊(cè)成功了,這時(shí)可以換一個(gè)熱鍵測(cè)試
 
 
def thread_it(func, *args):
  t = Thread(target=func, args=args)
  t.setDaemon(True)
  t.start()
 
 
def settimeout(func, sec):
  def inner():
    func()
    Timer(sec, inner).start()
 
  thread_it(inner)
 
 
def setinterval(func, sec, tmrname, flag=True):
  global timer_dict
  timer_dict[tmrname] = flag
  print("已設(shè)置tqtimer啟用狀態(tài)為:{}".format(flag))
 
  def inner():
    global timer_dict
    if timer_dict[tmrname]:
      func()
      Timer(sec, inner).start()
 
  thread_it(inner)
 
 
def clearinterval(timername):
  global timer_dict
  timer_dict[timername] = False
  flag = timer_dict[timername]
  print("已設(shè)置tqtimer啟用狀態(tài)為:{}".format(flag))
 
 
def test_start():
  print("按下了開(kāi)始鍵...the programe is running")
 
 
def test_stop():
  print("按下了停止鍵...the programe is stopped")
 
 
def run_ok():
  hotkey = Hotkey()
  hotkey.start()
  fn = hotkey.callback(0, test_start)
  fn = hotkey.callback(1, test_stop)
  thread_it(fn)
  sleep(0.5)
  count = activeCount()
  print(f"當(dāng)前總線程數(shù)量:{count}")
  print('當(dāng)前線程列表:', enumerate())
  print('熱鍵注冊(cè)初始化完畢,嘗試按組合鍵alt+F9 或者單鍵F10看效果')
  while True:
    pass
 
 
if __name__ == '__main__':
  run_ok()

這里是沒(méi)弄界面的源碼,所以我就把主線程死循環(huán)阻塞了。運(yùn)行后按alt+F9會(huì)打印按下了開(kāi)始鍵,按F10會(huì)打印按下了停止鍵。

如果你在tkinter里面跑,直接把run_ok函數(shù)后面的while True:pass刪掉,然后在init函數(shù)里面加入run_ok()就行了。這里指的用PAGE設(shè)計(jì)的tkinter程序哈!

那么窗體創(chuàng)建完畢就會(huì)自動(dòng)阻塞主線程,其他監(jiān)控?zé)徭I的線程隨主線程結(jié)束。啟動(dòng)期間獨(dú)立運(yùn)行互不干擾。

到此這篇關(guān)于python3注冊(cè)全局熱鍵的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)python3 注冊(cè)全局熱鍵內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python實(shí)現(xiàn)提取語(yǔ)句中的人名

    Python實(shí)現(xiàn)提取語(yǔ)句中的人名

    這篇文章主要為大家介紹一個(gè)小工具:可以將語(yǔ)句中的人名提取出來(lái)。文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-01-01
  • Pytorch BCELoss和BCEWithLogitsLoss的使用

    Pytorch BCELoss和BCEWithLogitsLoss的使用

    這篇文章主要介紹了Pytorch BCELoss和BCEWithLogitsLoss的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 跟老齊學(xué)Python之編寫類之三子類

    跟老齊學(xué)Python之編寫類之三子類

    本文已經(jīng)是編寫類系列的第三篇了,也是最后一篇,介紹下子類,也算是個(gè)小總結(jié)吧,有需要的朋友可以參考下
    2014-10-10
  • pygame游戲之旅 載入小車圖片、更新窗口

    pygame游戲之旅 載入小車圖片、更新窗口

    這篇文章主要為大家詳細(xì)介紹了pygame游戲之旅的第3篇,教大家如何載入小車圖片、更新窗口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • python?HZK16字庫(kù)使用詳解

    python?HZK16字庫(kù)使用詳解

    這篇文章主要介紹了python?HZK16字庫(kù)使用,本文結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • Pytest初學(xué)者快速上手高效Python測(cè)試指南

    Pytest初學(xué)者快速上手高效Python測(cè)試指南

    這篇文章主要為大家介紹了Pytest初學(xué)者快速上手的高效Python測(cè)試指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 最新評(píng)論