243 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env python3
 | ||
| ###############################################################
 | ||
| # 版本:1.8.0
 | ||
| # 更新时间:2022年07月26日
 | ||
| # Need: unix, python3-tk, python3-pip, pymouse, keyboard
 | ||
| ###############################################################
 | ||
| import os
 | ||
| import sys
 | ||
| import time
 | ||
| import json
 | ||
| import shutil
 | ||
| import keyboard
 | ||
| import traceback
 | ||
| import ttkthemes
 | ||
| import pyautogui
 | ||
| import threading
 | ||
| import updatekiller
 | ||
| import tkinter as tk
 | ||
| import tkinter.ttk as ttk
 | ||
| import tkinter.messagebox as messagebox
 | ||
| import tkinter.filedialog as filedialog
 | ||
| ########################
 | ||
| #
 | ||
| ########################
 | ||
| def Inputt(key):
 | ||
|     if key.event_type == "up":
 | ||
|         global setting
 | ||
|         if setting:
 | ||
|             Setting(key)
 | ||
|         else:
 | ||
|             Mouse(key)
 | ||
| 
 | ||
| def Open():
 | ||
|     path = filedialog.askopenfilename(title="打开", filetypes=[["json 文件", "*.json"], ["全部文件", ["*.*"]]])
 | ||
|     if not path == "" or path == ():
 | ||
|         shutil.copy(path, get_home() + "/.config/uengine-keyboard/key.json")
 | ||
|         if messagebox.askyesno(title="提示", message="导入成功!是否现在重启程序以便生效?"):
 | ||
|             ReStartProgram()
 | ||
| 
 | ||
| def Save():
 | ||
|     path = filedialog.asksaveasfilename(title="打开", filetypes=[["json 文件", "*.json"], ["全部文件", ["*.*"]]])
 | ||
|     if not path == "" or path == ():
 | ||
|         shutil.copy(get_home() + "/.config/uengine-keyboard/key.json", path)
 | ||
|         messagebox.showinfo(title="提示", message="导出成功!")
 | ||
| 
 | ||
| # 重启本应用程序
 | ||
| def ReStartProgram()->"重启本应用程序":
 | ||
|     python = sys.executable
 | ||
|     os.execl(python, python, * sys.argv)
 | ||
| 
 | ||
| 
 | ||
| def Mouse(key):
 | ||
|     print(keybo)
 | ||
|     if keybo.__contains__(key.name):
 | ||
|         print(keybo[key.name]["MousePlace"])
 | ||
|         pyautogui.FAILSAFE = False
 | ||
|         try:
 | ||
|             print((keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]))
 | ||
|             pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])
 | ||
|             
 | ||
|         except:
 | ||
|             traceback.print_exc()
 | ||
| 
 | ||
| def Setting(key):
 | ||
|     if key.event_type == 'up':
 | ||
|         keybo[key.name] = {"Mouse": "Left", "MousePlace": pyautogui.position()}
 | ||
|         write_txt("{}/.config/uengine-keyboard/key.json".format(get_home()), json.dumps(keybo))
 | ||
|         global inputs
 | ||
|         inputs = True
 | ||
|         global setting
 | ||
|         setting = False
 | ||
|         return False
 | ||
| 
 | ||
| def ShowTips():
 | ||
|     global close
 | ||
|     try:
 | ||
|         if setting:
 | ||
|             settingLabelText.set('''设置方法:把鼠标移动带所需位置然后按下需要设置的按键即可({}x{})
 | ||
| 提示:
 | ||
| 1、目前不支持同时按两个及以上按键,只支持在单一时间内按一个按键;
 | ||
| 2、使用映射不能关闭本窗口,但可以最小化;
 | ||
| 3、本程序需要 root 权限才能使用;
 | ||
| 4、映射时会占用鼠标,所以在使用时最好不要使用鼠标;'''.format(pyautogui.position()[0], pyautogui.position()[1]))
 | ||
|             settingButton.configure(state=tk.DISABLED)
 | ||
|         else:
 | ||
|             settingLabelText.set('''点击“设置”按钮设置映射({}x{})
 | ||
| 提示:
 | ||
| 1、目前不支持同时按两个及以上按键,只支持在单一时间内按一个按键;
 | ||
| 2、使用映射不能关闭本窗口,但可以最小化;
 | ||
| 3、本程序需要 root 权限才能使用;
 | ||
| 4、映射时会占用鼠标,所以在使用时最好不要使用鼠标;'''.format(pyautogui.position()[0], pyautogui.position()[1]))
 | ||
|             settingButton.configure(state=tk.NORMAL) 
 | ||
|         time.sleep(0.1)
 | ||
|         if not close:
 | ||
|             ShowTips()
 | ||
|     except:
 | ||
|         traceback.print_exc()
 | ||
|         print(close)
 | ||
|         if not close:
 | ||
|             ShowTips()
 | ||
| 
 | ||
| def Closing():
 | ||
|     global close
 | ||
|     close = True
 | ||
|     # 偷懒了,直接强制关闭进程
 | ||
|     os.system(f"kill {os.getpid()}")
 | ||
| 
 | ||
| 
 | ||
| def Key():
 | ||
|     keyboard.hook(Inputt)
 | ||
| 
 | ||
| # 获取用户主目录
 | ||
| def get_home()->"获取用户主目录":
 | ||
|     return os.path.expanduser('~')
 | ||
| 
 | ||
| # 写入文本文档
 | ||
| def write_txt(path: "路径", things: "内容")->"写入文本文档": 
 | ||
|     file = open(path, 'w', encoding='UTF-8')  # 设置文件对象
 | ||
|     file.write(things)  # 写入文本
 | ||
|     file.close()  # 关闭文本对象
 | ||
| 
 | ||
| # 读取文本文档
 | ||
| def readtxt(path: "路径")->"读取文本文档":
 | ||
|     f = open(path, "r")  # 设置文件对象
 | ||
|     str = f.read()       # 获取内容
 | ||
|     f.close()            # 关闭文本对象
 | ||
|     return str           # 返回结果
 | ||
| 
 | ||
| def Settings():
 | ||
|     global setting
 | ||
|     setting = True
 | ||
| 
 | ||
| def Clean():
 | ||
|     if messagebox.askokcancel(title="提示", message="你确定要删除吗?"):
 | ||
|         shutil.rmtree("{}/.config/uengine-keyboard".format(get_home()))
 | ||
|         if messagebox.askyesno(title="提示", message="删除成功!是否现在重启程序以便生效?"):
 | ||
|             ReStartProgram()
 | ||
| 
 | ||
| def About():
 | ||
|     threading.Thread(target=os.system, args=["{}/uengine-runner-about".format(programPath)]).start()
 | ||
| 
 | ||
| lock = False
 | ||
| def ThreadCheck():
 | ||
|     global lock
 | ||
|     lock = True
 | ||
|     pyautogui.position()
 | ||
|     lock = False
 | ||
| 
 | ||
| def RestartProgramTimer():
 | ||
|     threading.Thread(target=ThreadCheck).start()
 | ||
|     time.sleep(0.1)
 | ||
|     if lock:
 | ||
|         ReStartProgram()
 | ||
|     RestartProgramTimer()
 | ||
| 
 | ||
| ###################
 | ||
| #
 | ||
| ###################
 | ||
| if not os.path.exists("{}/.config/uengine-keyboard".format(get_home())):
 | ||
|     os.mkdir("{}/.config/uengine-keyboard".format(get_home()))
 | ||
| if not os.path.exists("{}/.config/uengine-keyboard/key.json".format(get_home())):
 | ||
|     write_txt("{}/.config/uengine-keyboard/key.json".format(get_home()), "{}")
 | ||
| 
 | ||
| ###################
 | ||
| #
 | ||
| ###################
 | ||
| setting = False
 | ||
| close = False
 | ||
| programPath = os.path.split(os.path.realpath(__file__))[0]  # 返回 string
 | ||
| iconPath = "{}/icon.png".format(os.path.split(os.path.realpath(__file__))[0])
 | ||
| keybo = json.loads(readtxt("{}/.config/uengine-keyboard/key.json".format(get_home())))
 | ||
| version = json.loads(readtxt("{}/information.json".format(programPath)))["Version"]
 | ||
| pyautogui.PAUSE = 0
 | ||
| 
 | ||
| ###################
 | ||
| # 判断是不是 root
 | ||
| ###################
 | ||
| if os.geteuid() != 0:
 | ||
|     print("不是以 root 权限运行本程序!")
 | ||
|     root = tk.Tk()
 | ||
|     root.overrideredirect(1)
 | ||
|     root.withdraw()
 | ||
|     messagebox.showerror(title="错误", message="不是以 root 权限运行本程序!")
 | ||
|     sys.exit(1)
 | ||
| 
 | ||
| ###################
 | ||
| #
 | ||
| ###################
 | ||
| window = tk.Tk()
 | ||
| win = ttk.Frame(window)
 | ||
| show = ttk.Frame(win)
 | ||
| 
 | ||
| settingLabelText = tk.StringVar()
 | ||
| 
 | ||
| # 设置菜单栏
 | ||
| menu = tk.Menu(window, tearoff=0, background="white")  
 | ||
| programMenu = tk.Menu(menu, tearoff=0, background="white")
 | ||
| aboutMenu = tk.Menu(menu, tearoff=0, background="white")
 | ||
| 
 | ||
| settingLabel = ttk.Label(win, textvariable=settingLabelText)
 | ||
| 
 | ||
| settingMouseToKeyboard = ttk.Button(show, text="启动键盘映射(已启用)")
 | ||
| settingButton = ttk.Button(show, text="添加或覆盖键盘映射设置", command=Settings)
 | ||
| 
 | ||
| settingMouseToKeyboard.configure(state=tk.DISABLED)
 | ||
| 
 | ||
| style = ttkthemes.ThemedStyle(window)
 | ||
| style.set_theme("breeze")
 | ||
| window.protocol('WM_DELETE_WINDOW', Closing)
 | ||
| window.resizable(0, 0)
 | ||
| window.iconphoto(False, tk.PhotoImage(file=iconPath))
 | ||
| window.title("UEngine 键盘映射 {}".format(version))
 | ||
| 
 | ||
| menu.add_cascade(label="程序", menu=programMenu)
 | ||
| menu.add_cascade(label="帮助", menu=aboutMenu)
 | ||
| menu.configure(activebackground="dodgerblue")
 | ||
| 
 | ||
| programMenu.add_command(label="导入映射设置", command=Open)
 | ||
| programMenu.add_command(label="导出映射设置", command=Save)
 | ||
| programMenu.add_command(label="删除所有映射设置", command=Clean)
 | ||
| programMenu.add_separator()
 | ||
| programMenu.add_command(label="退出程序", command=sys.exit)
 | ||
| programMenu.configure(activebackground="dodgerblue")
 | ||
| 
 | ||
| aboutMenu.add_command(label="关于", command=About)
 | ||
| 
 | ||
| window.config(menu=menu)  # 显示菜单栏
 | ||
| 
 | ||
| show.grid(row=1, column=0)
 | ||
| 
 | ||
| settingLabel.grid(row=0, column=0)
 | ||
| 
 | ||
| settingMouseToKeyboard.grid(row=0, column=0)
 | ||
| settingButton.grid(row=0, column=1)
 | ||
| 
 | ||
| win.pack(fill="both", expand="yes")
 | ||
| keys = threading.Thread(target=Key)
 | ||
| keys.start()
 | ||
| threading.Thread(target=ShowTips).start()
 | ||
| pyautogui.FAILSAFE = False
 | ||
| threading.Thread(target=RestartProgramTimer).start()
 | ||
| window.mainloop()
 |