2021-08-26 15:24:26 +08:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
#########################################
|
2022-05-21 18:11:11 +08:00
|
|
|
|
# 版本:1.6.1
|
|
|
|
|
# 更新时间:2022年10月06日
|
2021-08-30 17:49:12 +08:00
|
|
|
|
# Need: unix, python3-tk, python3-pip, pymouse, keyboard
|
2021-08-26 15:24:26 +08:00
|
|
|
|
#########################################
|
|
|
|
|
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
|
2021-08-30 17:49:12 +08:00
|
|
|
|
import Xlib.threaded as threaded
|
|
|
|
|
#import pymouse.unix as pymouse
|
2021-08-26 15:24:26 +08:00
|
|
|
|
########################
|
|
|
|
|
#
|
|
|
|
|
########################
|
|
|
|
|
def Inputt(key):
|
2021-08-30 17:49:12 +08:00
|
|
|
|
if key.event_type == "up":
|
2021-08-26 15:24:26 +08:00
|
|
|
|
global setting
|
|
|
|
|
if setting:
|
|
|
|
|
Setting(key)
|
|
|
|
|
else:
|
|
|
|
|
Mouse(key)
|
2021-08-30 17:49:12 +08:00
|
|
|
|
#Mouse(key)
|
2021-08-26 15:24:26 +08:00
|
|
|
|
|
|
|
|
|
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):
|
2021-08-30 17:49:12 +08:00
|
|
|
|
print(keybo)
|
2021-08-26 15:24:26 +08:00
|
|
|
|
if keybo.__contains__(key.name):
|
|
|
|
|
print(keybo[key.name]["MousePlace"])
|
2021-08-30 17:49:12 +08:00
|
|
|
|
pyautogui.FAILSAFE = False
|
|
|
|
|
#os.system(programPath + "/mouse.py {} {}".format(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]))
|
2022-05-21 18:11:11 +08:00
|
|
|
|
try:
|
|
|
|
|
pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])
|
|
|
|
|
except:
|
|
|
|
|
traceback.print_exc()
|
2021-10-26 20:19:42 +08:00
|
|
|
|
#pyautogui.click(1500, 800)
|
2021-08-30 17:49:12 +08:00
|
|
|
|
#m.click(keybo[key.name]["MousePlace"][0],keybo[key.name]["MousePlace"][1])
|
2021-08-26 15:24:26 +08:00
|
|
|
|
|
|
|
|
|
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():
|
2022-05-21 18:11:11 +08:00
|
|
|
|
global close
|
2021-08-26 15:24:26 +08:00
|
|
|
|
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)
|
2022-05-21 18:11:11 +08:00
|
|
|
|
if not close:
|
|
|
|
|
ShowTips()
|
2021-08-26 15:24:26 +08:00
|
|
|
|
except:
|
2021-08-30 17:49:12 +08:00
|
|
|
|
traceback.print_exc()
|
2022-05-21 18:11:11 +08:00
|
|
|
|
print(close)
|
2021-08-30 17:49:12 +08:00
|
|
|
|
if not close:
|
|
|
|
|
ShowTips()
|
|
|
|
|
|
|
|
|
|
def Closing():
|
2022-05-21 18:11:11 +08:00
|
|
|
|
global close
|
2021-08-30 17:49:12 +08:00
|
|
|
|
close = True
|
|
|
|
|
window.destroy()
|
2022-05-21 18:11:11 +08:00
|
|
|
|
#key.close()
|
|
|
|
|
#stop_thread(keys)
|
|
|
|
|
keyboard.unhook(Inputt)
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
2021-08-26 15:24:26 +08:00
|
|
|
|
|
|
|
|
|
def Key():
|
|
|
|
|
keyboard.hook(Inputt)
|
|
|
|
|
|
|
|
|
|
# 获取用户主目录
|
|
|
|
|
def get_home()->"获取用户主目录":
|
|
|
|
|
return os.path.expanduser('~')
|
|
|
|
|
|
|
|
|
|
# 写入文本文档
|
2021-08-30 17:49:12 +08:00
|
|
|
|
def write_txt(path: "路径", things: "内容")->"写入文本文档":
|
2021-08-26 15:24:26 +08:00
|
|
|
|
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()
|
|
|
|
|
|
|
|
|
|
###################
|
|
|
|
|
#
|
|
|
|
|
###################
|
|
|
|
|
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
|
2021-08-30 17:49:12 +08:00
|
|
|
|
close = False
|
2021-08-26 15:24:26 +08:00
|
|
|
|
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"]
|
2022-05-21 18:11:11 +08:00
|
|
|
|
pyautogui.PAUSE = 0
|
2021-08-26 15:24:26 +08:00
|
|
|
|
|
|
|
|
|
###################
|
|
|
|
|
# 判断是不是 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")
|
2021-08-30 17:49:12 +08:00
|
|
|
|
window.protocol('WM_DELETE_WINDOW', Closing)
|
2021-08-26 15:24:26 +08:00
|
|
|
|
window.resizable(0, 0)
|
|
|
|
|
window.iconphoto(False, tk.PhotoImage(file=iconPath))
|
2021-08-30 17:49:12 +08:00
|
|
|
|
window.title("UEngine 键盘映射 {}".format(version))
|
2021-08-26 15:24:26 +08:00
|
|
|
|
|
|
|
|
|
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")
|
2021-08-30 17:49:12 +08:00
|
|
|
|
#threaded.lock.allocate_lock()
|
2022-05-21 18:11:11 +08:00
|
|
|
|
keys = threading.Thread(target=Key)
|
|
|
|
|
keys.start()
|
2021-08-26 15:24:26 +08:00
|
|
|
|
threading.Thread(target=ShowTips).start()
|
2021-08-30 17:49:12 +08:00
|
|
|
|
pyautogui.FAILSAFE = False
|
|
|
|
|
'''def B(key):
|
|
|
|
|
if key.event_type == "up":
|
|
|
|
|
print(pyautogui.position())
|
|
|
|
|
print(key.name)
|
|
|
|
|
pyautogui.click(1500, 800)
|
|
|
|
|
keyboard.hook(B)
|
|
|
|
|
keyboard.wait()'''
|
2021-08-26 15:24:26 +08:00
|
|
|
|
window.mainloop()
|