2021-08-26 15:24:26 +08:00
|
|
|
|
#!/usr/bin/env python3
|
2022-07-26 14:57:48 +08:00
|
|
|
|
###############################################################
|
|
|
|
|
# 版本:1.8.0
|
|
|
|
|
# 更新时间:2022年07月26日
|
2021-08-30 17:49:12 +08:00
|
|
|
|
# Need: unix, python3-tk, python3-pip, pymouse, keyboard
|
2022-07-26 14:57:48 +08:00
|
|
|
|
###############################################################
|
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
|
2023-01-01 12:16:31 +08:00
|
|
|
|
import updatekiller
|
2021-08-26 15:24:26 +08:00
|
|
|
|
import tkinter as tk
|
|
|
|
|
import tkinter.ttk as ttk
|
|
|
|
|
import tkinter.messagebox as messagebox
|
|
|
|
|
import tkinter.filedialog as filedialog
|
2023-01-18 15:42:49 +08:00
|
|
|
|
print("山坡羊·潼关怀古")
|
|
|
|
|
print("""峰峦如聚,波涛如怒,山河表里潼关路。望西都,意踌躇。
|
|
|
|
|
伤心秦汉经行处,宫阙万间都做了土。兴,百姓苦;亡,百姓苦。
|
|
|
|
|
|
|
|
|
|
译文:(华山的)山峰从四面八方汇聚,(黄河的)波涛像发怒似的汹涌。潼关外有黄河,内有华山,山河雄伟,地势险要。遥望古都长安,陷于思索之中。从秦汉宫遗址经过,引发无限伤感,万间宫殿早已化作了尘土,一朝兴盛,百姓受苦;一朝灭亡,百姓依旧受苦。""")
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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
|
2022-05-21 18:11:11 +08:00
|
|
|
|
try:
|
2022-07-26 14:57:48 +08:00
|
|
|
|
print((keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1]))
|
2022-05-21 18:11:11 +08:00
|
|
|
|
pyautogui.click(keybo[key.name]["MousePlace"][0], keybo[key.name]["MousePlace"][1])
|
2022-07-26 14:57:48 +08:00
|
|
|
|
|
2022-05-21 18:11:11 +08:00
|
|
|
|
except:
|
|
|
|
|
traceback.print_exc()
|
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
|
2022-07-26 14:57:48 +08:00
|
|
|
|
# 偷懒了,直接强制关闭进程
|
|
|
|
|
os.system(f"kill {os.getpid()}")
|
2022-05-21 18:11:11 +08:00
|
|
|
|
|
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()
|
|
|
|
|
|
2022-07-26 14:57:48 +08:00
|
|
|
|
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()
|
|
|
|
|
|
2021-08-26 15:24:26 +08:00
|
|
|
|
###################
|
|
|
|
|
#
|
|
|
|
|
###################
|
|
|
|
|
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")
|
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
|
2022-07-26 14:57:48 +08:00
|
|
|
|
threading.Thread(target=RestartProgramTimer).start()
|
2023-01-01 12:16:31 +08:00
|
|
|
|
window.mainloop()
|