241 lines
7.8 KiB
Python
Executable File
241 lines
7.8 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 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() |