i道i的鼠标键盘小工具,拥有鼠标操作,键盘操作,键盘鼠标录制,录制文件编辑的功能,现在正在测试阶段,欢迎试用与反馈bug。
下载链接:i道i的鼠标键盘小工具.exe
代码如下:(上千行粘贴到csdn挺容易卡死的)
这个没有分类整理,不过都有注释,能看,等测试完了或许会整理一下(或许)
import time # 记录时间和线程睡眠用
import pickle # 保存变量用
import tkinter as tk # gui用
import tkinter.messagebox # 弹出来的对话框
import tkinter.filedialog # 文件相关窗口
from tkinter import ttk # 仅仅用到了下拉列表
from pynput import mouse # 鼠标操作
from pynput import keyboard # 键盘操作
from pynput.mouse import Controller, Button
from threading import Thread # 进程
# 避免玩脱的关闭程序,没得说,就一直监听,一旦遇到设定的键了,赶紧关窗口
# 也兼职监听停止所有功能的操作
def Close_Program():
def on_press(key): # 碰到按键就记录处理
global close_program, stop_all_key
now_key.add(key) # 当前按下的键进入集合
be_tap = 1 # 存在标记
be_t = 1
for i in close_program: # 关闭程序任何一个开始按键
if not i in now_key: # 没有按下
be_tap = 0 # 不存在,不允许
break
if be_tap: # 检测到所有开始按键/触发键
main_window.destroy()
for i in stop_all_key:
if not i in now_key: # 没有按下
be_t = 0 # 不存在,不允许
break
if be_t: # 停止所有操作
for i in range(1, len(gui_mouse)):
Mouse_Gui_Stop(gui_mouse[i])
for i in range(1, len(gui_fingerboard)):
Fingerboard_Gui_Stop(gui_fingerboard[i])
for i in range(1, len(gui_transcribe)):
Transcribe_Gui_Stop(gui_transcribe[i])
def on_release(key):
now_key.discard(key)
global main_window, stop_listener, gui_mouse, gui_fingerboard, gui_transcribe
now_key = set()
stop_listener = keyboard.Listener(on_press=on_press, on_release=on_release)
stop_listener.start()
# 对于文件,我们可以选择保存所有的gui,打开的时候直接替换gui即可,方便省事,bug少,缺点就是保存文件体积大,
# 或者,写一个保存文件函数和一个打开文件函数,提取gui里的关键信息,比如选项变量,按钮的值之类的,打开时再根据这些变量来更改gui的值,
#
# 打开文件函数
def Open_File():
def Key_Str(b):
b['text'] = ''
if b.key is None:
b['text'] = 'None'
return
for i in b.key:
b['text'] = b['text'] + str(i) + '+'
b['text'] = b['text'][0:-1]
file_path = tk.filedialog.askopenfilename() # 选择打开什么文件,返回文件名
if file_path.strip() != '': # 是空的时候,往往没有选择,直接关闭窗口
global gui_mouse, gui_fingerboard, gui_transcribe, close_program, stop_all_key
try:
file = open(file_path, 'rb')
data = pickle.load(file) # 数据取出来
if not ('name' in data) or data['name'] != 'i道i的鼠标键盘小工具':
tk.messagebox.showwarning(title='警告!', message='文件错误,非本程序所需文件')
file.close()
return
file.close()
except:
tk.messagebox.showwarning(title='警告!',message='文件错误,文件可能损坏')
return
# 开始用读取到的数据替换当前变量
close_program = data['close_program']
stop_all_key = data['stop_all_key']
for i in data['gui_mouse']:
Add_Mouse() # 创建鼠标gui
gui_mouse[-1].key.set(i['key'])
gui_mouse[-1].click_type.set(i['click_type'])
gui_mouse[-1].click_seat.set(i['click_seat'])
gui_mouse[-1].sparked_b.key = i['sparked_key']
Key_Str(gui_mouse[-1].sparked_b)
gui_mouse[-1].stop_b.key = i['stop_key']
Key_Str(gui_mouse[-1].stop_b)
gui_mouse[-1].number.set(i['number'])
gui_mouse[-1].press_time.set(i['press_time'])
gui_mouse[-1].release_time.set(i['release_time'])
for i in data['gui_fingerboard']:
Add_Fingerboard() # 创建键盘gui
gui_fingerboard[-1].use.set(i['use'])
Chenge_Fingerboard_l(gui_fingerboard[-1]) # 显示的界面
gui_fingerboard[-1].sparked_b.key = i['sparked_key']
Key_Str(gui_fingerboard[-1].sparked_b)
gui_fingerboard[-1].stop_b.key = i['stop_key']
Key_Str(gui_fingerboard[-1].stop_b)
gui_fingerboard[-1].l_frame_1.text.insert('0.0', i['text'])
gui_fingerboard[-1].presskey_b.key = i['presskey_key']
Key_Str(gui_fingerboard[-1].presskey_b)
gui_fingerboard[-1].number.set(i['number'])
gui_fingerboard[-1].press_time.set(i['press_time'])
gui_fingerboard[-1].release_time.set(i['release_time'])
for i in data['gui_transcribe']:
Add_Transcribe() # 创建录制gui
gui_transcribe[-1].l_frame.record_data = i['record_data']
gui_transcribe[-1].l_frame.record_use.set(i['record_use'])
gui_transcribe[-1].l_frame.sparked_b.key = i['l_sparked_key']
Key_Str(gui_transcribe[-1].l_frame.sparked_b)
gui_transcribe[-1].l_frame.stop_b.key = i['l_stop_key']
Key_Str(gui_transcribe[-1].l_frame.sparked_b)
gui_transcribe[-1].sparked_b.key = i['sparked_key']
Key_Str(gui_transcribe[-1].sparked_b)
gui_transcribe[-1].stop_b.key = i['stop_key']
Key_Str(gui_transcribe[-1].stop_b)
# 保存文件函数
def Save_File():
global gui_mouse, gui_fingerboard, gui_transcribe, close_program, stop_all_key
file_path = tk.filedialog.asksaveasfilename() # 选择文件保存位置和名字
if file_path.strip() != '': # 是空的时候,往往没有选择,直接关闭窗口
return
# 开始保存所有需要保存的关键数据
data = {'gui_mouse': [], 'gui_fingerboard': [], 'gui_transcribe': [], 'close_program': close_program,
'stop_all_key': stop_all_key, 'name': 'i道i的鼠标键盘小工具'} # 存数据用
try: # 存鼠标数据
for i in gui_mouse[1:]:
data['gui_mouse'].append(
{'key': i.key.get(), 'click_type': i.click_type.get(), 'click_seat': i.click_seat.get(),
'sparked_key': i.sparked_b.key, 'stop_key': i.stop_b.key, 'number': i.number.get(),
'press_time': i.press_time.get(), 'release_time': i.release_time.get()})
except:
tk.messagebox.showwarning(title='警告!',
message='鼠标数据保存错误,请检查输入的数据是否正确。\n'
'不支持表达式,如:5+2用于数值的创建')
return
try:
for i in gui_fingerboard[1:]: # 存键盘数据
data['gui_fingerboard'].append(
{'use': i.use.get(), 'sparked_key': i.sparked_b.key, 'stop_key': i.stop_b.key,
'text': i.l_frame_1.text.get('0.0', 'end'), 'presskey_key': i.presskey_b.key,
'number': i.number.get(), 'press_time': i.press_time.get(),
'release_time': i.release_time.get()})
except:
tk.messagebox.showwarning(title='警告!',
message='键盘数据保存错误,请检查输入的数据是否正确。\n'
'不支持表达式,如:5+2用于数值的创建')
return
try:
for i in gui_transcribe[1:]: # 存录制数据
data['gui_transcribe'].append(
{'record_data': i.l_frame.record_data, 'record_use': i.l_frame.record_use.get(),
'l_sparked_key': i.l_frame.sparked_b.key, 'l_stop_key': i.l_frame.stop_b.key,
'sparked_key': i.sparked_b.key, 'stop_key': i.stop_b.key, })
except:
tk.messagebox.showwarning(title='警告!',
message='录制数据保存错误,请检查输入的数据是否正确。\n'
'不支持表达式,如:5+2用于数值的创建')
return
file = open(file_path, 'wb')
pickle.dump(data, file)
file.close()
# 设置函数,设置各个操作的键位
def Set_Up():
def Define():
global close_program, stop_all_key
close_program = close_program_b.key
stop_all_key = stop_all_key_b.key
Set_Up_window.destroy()
global main_window, close_program, stop_all_key
Set_Up_window = tk.Toplevel(main_window) # 生成设置窗口
Set_Up_window.title("设置")
Set_Up_window.geometry("800x200")
close_program_l = tk.Label(Set_Up_window, text='关闭程序:')
stop_all_key_l = tk.Label(Set_Up_window, text='关闭所有功能:')
close_program_b = tk.Button(Set_Up_window, text='', )
stop_all_key_b = tk.Button(Set_Up_window, text='', )
close_program_b.key = close_program[:]
stop_all_key_b.key = stop_all_key[:]
for i in close_program_b.key:
close_program_b['text'] = close_program_b['text'] + str(i) + '+'
for i in stop_all_key_b.key:
stop_all_key_b['text'] = stop_all_key_b['text'] + str(i) + '+'
close_program_b['text'] = close_program_b['text'][0:-1]
stop_all_key_b['text'] = stop_all_key_b['text'][0:-1]
close_program_b['command'] = lambda button=close_program_b: Change_Key_B(button)
stop_all_key_b['command'] = lambda button=stop_all_key_b: Change_Key_B(button)
define_b = tk.Button(Set_Up_window, text='确定', command=Define)
close_program_l.grid(row=0, column=0, )
close_program_b.grid(row=0, column=1, )
stop_all_key_l.grid(row=1, column=0, )
stop_all_key_b.grid(row=1, column=1, )
define_b.grid(row=2, column=0, )
# 放缩控制
for i in range(2):
Set_Up_window.columnconfigure(i, weight=1)
Set_Up_window.rowconfigure(i, weight=1)
Set_Up_window.rowconfigure(2, weight=1)
# 录制文件编辑方法
def Record_Edit(data):
# 监听键盘按钮,更改按键的值,只监听一个按键
def Change_Key():
def on_press(key): # 碰到按键就停止
if s != edit_window.fingerboard_data_gui.entry.Selected:
return False
edit_window.fingerboard_content.b_button.key = key
edit_window.fingerboard_content.b_button['text'] = key
return False
s = edit_window.fingerboard_data_gui.entry.Selected
edit_window.fingerboard_content.b_button['text'] = ''
listener = keyboard.Listener(on_press=on_press)
listener.start()
def Set(): # 确定函数 关闭+保存窗口,含确认
if tk.messagebox.askokcancel("确定", "确定更改录制文件?"):
data[0] = edit_window.mouse_data_gui.data
data[1] = edit_window.fingerboard_data_gui.data
edit_window.destroy()
# 监听下回鼠标点击位置
def Seat_Mouse():
def on_click(x, y, button, pressed):
if pressed and button == mouse.Button.left: # 碰到按下鼠标左键就更改文本框内容
edit_window.mouse_content.x.set(x)
edit_window.mouse_content.y.set(y)
listener.stop()
# 使用事件监听进程,监听到鼠标按下左键,返回位置到文本框
listener = mouse.Listener(on_click=on_click)
listener.start()
# 添加操作
def Add_Kind(gui):
new_data = {'kind': 0, 'time': time.time(), 'sleep_time': 0} # 新项,无操作
gui.data.insert(gui.entry.Selected + 1, new_data) # 插入选中位置下一位,若没选,插入开头。
gui.e_data.set(gui.data) # 更新显示
# 删除操作
def Remove_Kind(gui):
if gui.entry.Selected < 0:
return # 负数直接跳过,python 负数索引指倒数,怕乱删
del gui.data[gui.entry.Selected] # 删除当前选中的值
gui.entry.Selected = -1 # 取消当前选择
gui.e_data.set(gui.data) # 更新显示
def Setting_Mouse_Kind(event=None): # 鼠标类型设定,仅仅是按类型禁用部分组件
x = edit_window.mouse_content.c_kind['value'].index(
edit_window.mouse_content.c_kind.get())
edit_window.mouse_content.c_button['state'] = 'disabled'
edit_window.mouse_content.c_pressed['state'] = 'disabled'
edit_window.mouse_content.e_x['state'] = 'disabled'
edit_window.mouse_content.e_y['state'] = 'disabled'
edit_window.mouse_content.e_dx['state'] = 'disabled'
edit_window.mouse_content.e_dy['state'] = 'disabled'
if x != 0: # 移动
edit_window.mouse_content.e_x['state'] = 'normal'
edit_window.mouse_content.e_y['state'] = 'normal'
if x == 2: # 按键
edit_window.mouse_content.c_button['state'] = 'normal'
edit_window.mouse_content.c_pressed['state'] = 'normal'
elif x == 3: # 滚动
edit_window.mouse_content.e_dx['state'] = 'normal'
edit_window.mouse_content.e_dy['state'] = 'normal'
def Setting_Fingerboard_Kind(event=None): # 键盘类型设定
x = edit_window.fingerboard_content.c_kind['value'].index(
edit_window.fingerboard_content.c_kind.get())
if x != 0:
edit_window.fingerboard_content.b_button['state'] = 'normal' # 不是无操作,启用
else:
edit_window.fingerboard_content.b_button['state'] = 'disabled'
def Selected_Mouse(event=None): # 选择鼠标列表框后的方法
index = edit_window.mouse_data_gui.entry.curselection() # 获取当前选中的位置
if len(index) != 1:
return
index = index[0]
edit_window.mouse_data_gui.entry.Selected = index
s_m_data = edit_window.mouse_data_gui.data[index] # 选中的数据
edit_window.mouse_content.c_kind.current(s_m_data['kind']) # 切换类型
Setting_Mouse_Kind() # 禁用组件
# 根据类型的不同,填入参数
edit_window.mouse_content.time.set(s_m_data['time'])
edit_window.mouse_content.sleep_time.set(s_m_data['sleep_time'])
if s_m_data['kind'] != 0: # 移动
edit_window.mouse_content.x.set(s_m_data['x'])
edit_window.mouse_content.y.set(s_m_data['y'])
if s_m_data['kind'] == 2: # 按键
if s_m_data['button'] == Button.left:
edit_window.mouse_content.c_button.current(0)
elif s_m_data['button'] == Button.middle:
edit_window.mouse_content.c_button.current(1)
elif s_m_data['button'] == Button.right:
edit_window.mouse_content.c_button.current(2)
elif s_m_data['button'] == Button.x1:
edit_window.mouse_content.c_button.current(3)
elif s_m_data['button'] == Button.x2:
edit_window.mouse_content.c_button.current(4)
if s_m_data['pressed']:
edit_window.mouse_content.c_pressed.current(0)
else:
edit_window.mouse_content.c_pressed.current(1)
elif s_m_data['kind'] == 3: # 滚动
edit_window.mouse_content.dx.set(s_m_data['dx'])
edit_window.mouse_content.dy.set(s_m_data['dy'])
def Selected_Fingerboard(event=None): # 选择键盘列表框后的方法
index = edit_window.fingerboard_data_gui.entry.curselection() # 获取当前选中的位置
if len(index) != 1:
return
index = index[0]
edit_window.fingerboard_data_gui.entry.Selected = index
s_m_data = edit_window.fingerboard_data_gui.data[index] # 选中的数据
edit_window.fingerboard_content.c_kind.current(s_m_data['kind']) # 切换类型
Setting_Fingerboard_Kind() # 禁用组件
# 根据类型的不同,填入参数
edit_window.fingerboard_content.time.set(s_m_data['time'])
edit_window.fingerboard_content.sleep_time.set(s_m_data['sleep_time'])
if s_m_data['kind'] != 0: # 有操作,设定键值
edit_window.fingerboard_content.b_button.key = s_m_data['key']
edit_window.fingerboard_content.b_button['text'] = s_m_data['key']
def Mouse_Change(): # 点击鼠标确定更改后的操作
index = edit_window.mouse_data_gui.entry.Selected # 获取当前选中的位置
if index < 0: # 负数,错误输入,不改(出现在删除节点之后,以及刚进入,未选择节点时)
return
change_data = {'kind': edit_window.mouse_content.c_kind['value'].index(
edit_window.mouse_content.c_kind.get())} # 一个字典,存需要的数据,替换data中的项
try:
change_data['time'] = edit_window.mouse_content.time.get() # 都有的时间
if change_data['kind'] != 0: # 移动
change_data['x'] = edit_window.mouse_content.x.get()
change_data['y'] = edit_window.mouse_content.y.get()
if change_data['kind'] == 2: # 按键
change_data['button'] = edit_window.mouse_content.c_button['value'].index(
edit_window.mouse_content.c_button.get())
if change_data['button'] == 0:
change_data['button'] = Button.left
elif change_data['button'] == 1:
change_data['button'] = Button.middle
elif change_data['button'] == 2:
change_data['button'] = Button.right
elif change_data['button'] == 3:
change_data['button'] = Button.x1
elif change_data['button'] == 4:
change_data['button'] = Button.x2
if edit_window.mouse_content.c_pressed.get() == '按下':
change_data['pressed'] = True
else:
change_data['pressed'] = False
elif change_data['kind'] == 3: # 滚动
change_data['dx'] = edit_window.mouse_content.dx.get()
change_data['dy'] = edit_window.mouse_content.dy.get()
change_data['sleep_time'] = edit_window.mouse_content.sleep_time.get() # 这个放后面为了保持顺序不变(好看用)
except:
tk.messagebox.showwarning(title='警告!',
message='输入数据错误,请检查输入的数据是否正确。\n'
'不支持表达式,如:5+2用于数值的创建')
return
if change_data['sleep_time'] < 0: # 睡眠负数警告
tk.messagebox.showwarning(title='警告!',
message='时间不能为负数,请检查输入的数据是否正确。\n'
'操作延迟时间,即睡眠时间不能为负数,操作时间随便填。')
return
edit_window.mouse_data_gui.data[index] = change_data # 替换数据
edit_window.mouse_data_gui.e_data.set(edit_window.mouse_data_gui.data) # 更改列表框的显示
def Fingerboard_Change(): # 点击键盘确定更改后的操作
index = edit_window.fingerboard_data_gui.entry.Selected # 获取当前选中的位置
if index < 0: # 负数,错误输入,不改(出现在删除节点之后,以及刚进入,未选择节点时)
return
change_data = {'kind': edit_window.fingerboard_content.c_kind['value'].index(
edit_window.fingerboard_content.c_kind.get())} # 一个字典,存需要的数据,替换data中的项
try:
change_data['time'] = edit_window.fingerboard_content.time.get() # 都有的时间
if change_data['kind'] != 0:
change_data['key'] = edit_window.fingerboard_content.b_button.key
if change_data['key'] is None: # 空按键警告
tk.messagebox.showwarning(title='警告!',
message='选择按下或松开时按键不能为空。\n'
'请设定按键的值。')
return
change_data['sleep_time'] = edit_window.fingerboard_content.sleep_time.get() # 这个放后面为了保持顺序不变
except:
tk.messagebox.showwarning(title='警告!',
message='输入数据错误,请检查输入的数据是否正确。\n'
'不支持表达式,如:5+2用于数值的创建')
return
if change_data['sleep_time'] < 0: # 睡眠负数警告
tk.messagebox.showwarning(title='警告!',
message='时间不能为负数,请检查输入的数据是否正确。\n'
'操作延迟时间,即睡眠时间不能为负数,操作时间随便填。')
return
edit_window.fingerboard_data_gui.data[index] = change_data # 替换数据
edit_window.fingerboard_data_gui.e_data.set(edit_window.fingerboard_data_gui.data) # 更改列表框的显示
def Resetting_gui(): # 打开页面前清除页面内容
for i in edit_window.data_bar.grid_slaves():
i.grid_forget()
for i in edit_window.content_bar.grid_slaves():
i.grid_forget()
def Open_Mouse(): # 打开鼠标操作界面
Resetting_gui()
edit_window.mouse_data_gui.grid(sticky="nsew")
edit_window.mouse_content.grid(sticky="nsew")
def Open_Fingerboard(): # 打开键盘操作界面
Resetting_gui()
edit_window.fingerboard_data_gui.grid(sticky="nsew")
edit_window.fingerboard_content.grid(sticky="nsew")
global main_window
edit_window = tk.Toplevel(main_window) # 生成编辑窗口
edit_window.title("录制文件编辑")
edit_window.geometry("1000x600")
edit_window.class_bar = tk.LabelFrame(edit_window, text="操作", bg='gainsboro') # 放左边容纳鼠标或键盘的框架
edit_window.class_bar.grid(row=0, column=0, rowspan=2, sticky="nsew")
edit_window.class_bar.class_bar = [
tk.Button(edit_window.class_bar, text="鼠标操作", command=Open_Mouse),
tk.Button(edit_window.class_bar, text="键盘操作", command=Open_Fingerboard),
tk.Button(edit_window.class_bar, text="确定", command=Set)] # 操作按钮组
for i in range(3):
edit_window.class_bar.class_bar[i].grid(row=i, column=0, padx=5, pady=2)
edit_window.data_bar = tk.LabelFrame(edit_window, text="数据栏", ) # 放右上,显示所有变量
edit_window.content_bar = tk.LabelFrame(edit_window, text="内容", ) # 放在右下,显示具体的操作
edit_window.data_bar.grid(row=0, column=1, sticky="nsew")
edit_window.content_bar.grid(row=1, column=1, sticky="nsew")
# 鼠标操作gui
edit_window.mouse_data_gui = tk.LabelFrame(edit_window.data_bar)
edit_window.mouse_data_gui.scroll_bar_x = tk.Scrollbar(edit_window.mouse_data_gui, orient=tk.HORIZONTAL) # 水平滚动条
edit_window.mouse_data_gui.scroll_bar_y = tk.Scrollbar(edit_window.mouse_data_gui, orient=tk.VERTICAL) # 垂直滚动条
edit_window.mouse_data_gui.data = data[0][:] # 实际上用的
edit_window.mouse_data_gui.e_data = tk.StringVar() # 面子上给用户看的
edit_window.mouse_data_gui.e_data.set(data[0])
edit_window.mouse_data_gui.entry = tk.Listbox( # 列表框,关联滚动条
edit_window.mouse_data_gui, xscrollcommand=edit_window.mouse_data_gui.scroll_bar_x.set,
yscrollcommand=edit_window.mouse_data_gui.scroll_bar_y.set, listvariable=edit_window.mouse_data_gui.e_data, )
edit_window.mouse_data_gui.entry.Selected = -1 # 这个用来保存选中的位置。
edit_window.mouse_data_gui.entry.bind("<<ListboxSelect>>", Selected_Mouse) # 绑定选中方法
edit_window.mouse_data_gui.scroll_bar_x.config(command=edit_window.mouse_data_gui.entry.xview)
edit_window.mouse_data_gui.scroll_bar_x.pack(side=tk.BOTTOM, fill=tk.X) # 靠下,拉满x
edit_window.mouse_data_gui.scroll_bar_y.config(command=edit_window.mouse_data_gui.entry.yview)
edit_window.mouse_data_gui.scroll_bar_y.pack(side=tk.RIGHT, fill=tk.Y) # 靠右,拉满y
edit_window.mouse_data_gui.entry.pack(fill=tk.BOTH, expand=1)
# 鼠标操作具体数据gui
edit_window.mouse_content = tk.LabelFrame(edit_window.content_bar)
# 鼠标相关数据关联变量:
edit_window.mouse_content.x = tk.IntVar() # 鼠标操作的位置
edit_window.mouse_content.y = tk.IntVar()
edit_window.mouse_content.dx = tk.IntVar() # 鼠标滚动坐标
edit_window.mouse_content.dy = tk.IntVar()
edit_window.mouse_content.time = tk.DoubleVar() # 按下的系统时间
edit_window.mouse_content.sleep_time = tk.DoubleVar() # 距离上一次 操作的时间
# 各种组件
edit_window.mouse_content.l_kind = tk.Label(edit_window.mouse_content, text='操作类型:') # 类型
edit_window.mouse_content.c_kind = ttk.Combobox(edit_window.mouse_content) # 下拉列表
edit_window.mouse_content.c_kind['value'] = ('无操作', '移动', '按键', '滚动')
edit_window.mouse_content.c_kind['state'] = 'readonly' # 只读
edit_window.mouse_content.c_kind.bind("<<ComboboxSelected>>", Setting_Mouse_Kind)
edit_window.mouse_content.c_kind.current(0) # 首选项
edit_window.mouse_content.l_button = tk.Label(edit_window.mouse_content, text='点击键位:')
edit_window.mouse_content.c_button = ttk.Combobox(edit_window.mouse_content)
edit_window.mouse_content.c_button['value'] = ('左键', '中键', '右键', '侧键1', '侧键2')
edit_window.mouse_content.c_button.current(0)
edit_window.mouse_content.l_pressed = tk.Label(edit_window.mouse_content, text='按下/放开:')
edit_window.mouse_content.c_pressed = ttk.Combobox(edit_window.mouse_content)
edit_window.mouse_content.c_pressed['value'] = ('按下', '放开')
edit_window.mouse_content.c_pressed.current(0)
edit_window.mouse_content.l_x = tk.Label(edit_window.mouse_content, text='鼠标位置x:')
edit_window.mouse_content.e_x = tk.Entry(edit_window.mouse_content, textvariable=edit_window.mouse_content.x)
edit_window.mouse_content.l_y = tk.Label(edit_window.mouse_content, text='鼠标位置y:')
edit_window.mouse_content.e_y = tk.Entry(edit_window.mouse_content, textvariable=edit_window.mouse_content.y)
edit_window.mouse_content.l_dx = tk.Label(edit_window.mouse_content, text='鼠标滚动dx:')
edit_window.mouse_content.e_dx = tk.Entry(edit_window.mouse_content, textvariable=edit_window.mouse_content.dx)
edit_window.mouse_content.l_dy = tk.Label(edit_window.mouse_content, text='鼠标滚动dy:')
edit_window.mouse_content.e_dy = tk.Entry(edit_window.mouse_content, textvariable=edit_window.mouse_content.dy)
edit_window.mouse_content.l_time = tk.Label(edit_window.mouse_content, text='操作时间:')
edit_window.mouse_content.e_time = tk.Entry(edit_window.mouse_content, textvariable=edit_window.mouse_content.time)
edit_window.mouse_content.l_sleep_time = tk.Label(edit_window.mouse_content, text='操作延迟时间:')
edit_window.mouse_content.e_sleep_time = tk.Entry(edit_window.mouse_content,
textvariable=edit_window.mouse_content.sleep_time)
edit_window.mouse_content.seat_mouse = tk.Button(edit_window.mouse_content, text='获取点击位置', command=Seat_Mouse)
edit_window.mouse_content.add_kind = tk.Button(edit_window.mouse_content, text='添加操作',
command=lambda gui=edit_window.mouse_data_gui: Add_Kind(gui))
edit_window.mouse_content.remove_kind = tk.Button(edit_window.mouse_content, text='删除操作',
command=lambda gui=edit_window.mouse_data_gui: Remove_Kind(gui))
edit_window.mouse_content.change_b = tk.Button(edit_window.mouse_content, text='确定更改', command=Mouse_Change)
edit_window.mouse_content.point_out_l = tk.Label(edit_window.mouse_content,
text='来自i道i的提示:按下按键后一定要记着放开,不会自动放开的')
Setting_Mouse_Kind()
edit_window.mouse_content.l_kind.grid(row=0, column=0, sticky='w')
edit_window.mouse_content.c_kind.grid(row=0, column=1, sticky='w')
edit_window.mouse_content.l_button.grid(row=1, column=0, sticky='w')
edit_window.mouse_content.c_button.grid(row=1, column=1, sticky='w')
edit_window.mouse_content.l_pressed.grid(row=2, column=0, sticky='w')
edit_window.mouse_content.c_pressed.grid(row=2, column=1, sticky='w')
edit_window.mouse_content.l_x.grid(row=0, column=2, sticky='w')
edit_window.mouse_content.e_x.grid(row=0, column=3, sticky='w')
edit_window.mouse_content.l_y.grid(row=0, column=4, sticky='w')
edit_window.mouse_content.e_y.grid(row=0, column=5, sticky='w', columnspan=2)
edit_window.mouse_content.l_dx.grid(row=1, column=2, sticky='w')
edit_window.mouse_content.e_dx.grid(row=1, column=3, sticky='w')
edit_window.mouse_content.l_dy.grid(row=1, column=4, sticky='w')
edit_window.mouse_content.e_dy.grid(row=1, column=5, sticky='w', columnspan=2)
edit_window.mouse_content.l_time.grid(row=2, column=2, sticky='w')
edit_window.mouse_content.e_time.grid(row=2, column=3, sticky='w')
edit_window.mouse_content.l_sleep_time.grid(row=3, column=2, sticky='w')
edit_window.mouse_content.e_sleep_time.grid(row=3, column=3, sticky='w')
edit_window.mouse_content.add_kind.grid(row=2, column=5, sticky='w', )
edit_window.mouse_content.remove_kind.grid(row=3, column=5, sticky='w', )
edit_window.mouse_content.seat_mouse.grid(row=2, column=6, sticky='w', )
edit_window.mouse_content.change_b.grid(row=3, column=1, sticky='w', )
edit_window.mouse_content.point_out_l.grid(row=4,column=1,columnspan=3)
# 键盘操作gui
edit_window.fingerboard_data_gui = tk.LabelFrame(edit_window.data_bar)
edit_window.fingerboard_data_gui.scroll_bar_x = tk.Scrollbar(edit_window.fingerboard_data_gui,
orient=tk.HORIZONTAL) # 水平滚动条
edit_window.fingerboard_data_gui.scroll_bar_y = tk.Scrollbar(edit_window.fingerboard_data_gui,
orient=tk.VERTICAL) # 垂直滚动条
edit_window.fingerboard_data_gui.data = data[1][:] # 实际上用的
edit_window.fingerboard_data_gui.e_data = tk.StringVar()
edit_window.fingerboard_data_gui.e_data.set(data[1])
edit_window.fingerboard_data_gui.entry = tk.Listbox( # 列表框,关联滚动条
edit_window.fingerboard_data_gui, xscrollcommand=edit_window.fingerboard_data_gui.scroll_bar_x.set,
yscrollcommand=edit_window.fingerboard_data_gui.scroll_bar_y.set,
listvariable=edit_window.fingerboard_data_gui.e_data, )
edit_window.fingerboard_data_gui.entry.Selected = -1 # 这个用来保存上一次选中的位置。
edit_window.fingerboard_data_gui.entry.bind("<<ListboxSelect>>", Selected_Fingerboard) # 绑定选中方法
edit_window.fingerboard_data_gui.scroll_bar_x.config(command=edit_window.fingerboard_data_gui.entry.xview)
edit_window.fingerboard_data_gui.scroll_bar_x.pack(side=tk.BOTTOM, fill=tk.X) # 靠下,拉满x
edit_window.fingerboard_data_gui.scroll_bar_y.config(command=edit_window.fingerboard_data_gui.entry.yview)
edit_window.fingerboard_data_gui.scroll_bar_y.pack(side=tk.RIGHT, fill=tk.Y) # 靠右,拉满y
edit_window.fingerboard_data_gui.entry.pack(fill=tk.BOTH, expand=1)
# 键盘操作具体数据gui
edit_window.fingerboard_content = tk.LabelFrame(edit_window.content_bar)
# 操作关联变量
edit_window.fingerboard_content.time = tk.DoubleVar()
edit_window.fingerboard_content.sleep_time = tk.DoubleVar()
# 各种组件
edit_window.fingerboard_content.l_kind = tk.Label(edit_window.fingerboard_content, text='操作类型:') # 类型
edit_window.fingerboard_content.c_kind = ttk.Combobox(edit_window.fingerboard_content) # 下拉列表
edit_window.fingerboard_content.c_kind['value'] = ('无操作', '按下', '松开')
edit_window.fingerboard_content.c_kind['state'] = 'readonly' # 只读
edit_window.fingerboard_content.c_kind.bind("<<ComboboxSelected>>", Setting_Fingerboard_Kind)
edit_window.fingerboard_content.c_kind.current(0) # 首选项
edit_window.fingerboard_content.l_button = tk.Label(edit_window.fingerboard_content, text='操作键位:')
edit_window.fingerboard_content.b_button = tk.Button(edit_window.fingerboard_content, command=Change_Key)
edit_window.fingerboard_content.b_button.key = None # 需要按下的键
edit_window.fingerboard_content.l_time = tk.Label(edit_window.fingerboard_content, text='操作时间:')
edit_window.fingerboard_content.e_time = tk.Entry(edit_window.fingerboard_content,
textvariable=edit_window.fingerboard_content.time)
edit_window.fingerboard_content.l_sleep_time = tk.Label(edit_window.fingerboard_content, text='操作延迟时间:')
edit_window.fingerboard_content.e_sleep_time = tk.Entry(edit_window.fingerboard_content,
textvariable=edit_window.fingerboard_content.sleep_time)
edit_window.fingerboard_content.add_kind = tk.Button(edit_window.fingerboard_content, text='添加操作', command=lambda
gui=edit_window.fingerboard_data_gui: Add_Kind(gui))
edit_window.fingerboard_content.remove_kind = tk.Button(edit_window.fingerboard_content, text='删除操作', command=lambda
gui=edit_window.fingerboard_data_gui: Remove_Kind(gui))
edit_window.fingerboard_content.change_b = tk.Button(edit_window.fingerboard_content, text='确定更改',
command=Fingerboard_Change)
edit_window.fingerboard_content.point_out_l = tk.Label(edit_window.fingerboard_content,
text='来自i道i的提示:按下按键后一定要记着放开,不会自动放开的')
Setting_Fingerboard_Kind()
edit_window.fingerboard_content.l_kind.grid(row=0, column=0, sticky='w', )
edit_window.fingerboard_content.c_kind.grid(row=0, column=1, sticky='w', )
edit_window.fingerboard_content.l_button.grid(row=0, column=2, sticky='w')
edit_window.fingerboard_content.b_button.grid(row=0, column=3, sticky='w', columnspan=2)
edit_window.fingerboard_content.l_time.grid(row=1, column=2, sticky='w')
edit_window.fingerboard_content.e_time.grid(row=1, column=3, sticky='w', columnspan=2)
edit_window.fingerboard_content.l_sleep_time.grid(row=2, column=2, sticky='w')
edit_window.fingerboard_content.e_sleep_time.grid(row=2, column=3, sticky='w', columnspan=2)
edit_window.fingerboard_content.add_kind.grid(row=1, column=1, sticky='w', )
edit_window.fingerboard_content.remove_kind.grid(row=2, column=1, sticky='w', )
edit_window.fingerboard_content.change_b.grid(row=0, column=6, sticky='w', )
edit_window.fingerboard_content.point_out_l.grid(row=4,column=1,columnspan=3)
# 放缩控制
edit_window.columnconfigure(1, weight=1)
edit_window.rowconfigure(0, weight=1)
edit_window.rowconfigure(1, weight=1)
edit_window.data_bar.rowconfigure(0, weight=1)
edit_window.content_bar.rowconfigure(0, weight=1)
edit_window.data_bar.columnconfigure(0, weight=1)
edit_window.content_bar.columnconfigure(0, weight=1)
# 录制文件删除方法
def Record_Delete(data):
if tk.messagebox.askokcancel("录制文件删除", "确定删除录制文件?"):
data.clear() # 删除上一回的录制
data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存鼠标
data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存键盘
# 菜单栏
def Generate_Menu(main_window):
menubar = tk.Menu(main_window) # 菜单栏
# 文件菜单是菜单栏的子菜单,且不能窗口化
submenu_file = tk.Menu(menubar, tearoff=False)
submenu_file.add_command(label='打开文件', command=Open_File) # 文件子菜单添加选项
submenu_file.add_command(label='保存文件', command=Save_File)
submenu_file.add_separator() # 分割线
submenu_file.add_command(label='设置', command=Set_Up) # command为要调用的函数
menubar.add_cascade(label='文件', menu=submenu_file) # 菜单添加文件子菜单项
return menubar
# gui删除,从gui_gather中删除gui,并更改其余gui的n值
def Delete_gui(gui_gather, gui, ):
gui.sparked_stop_tab = [True] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
for i in range(gui['text'], len(gui_gather)):
gui_gather[i]['text'] = int(gui_gather[i]['text']) - 1
gui_gather.remove(gui)
if works == 'mouse': # 判断当前类型
Common_Mouse() # 重新启动
elif works == 'fingerboard':
Common_Fingerboard()
elif works == 'transcribe':
Common_Transcribe()
# 监听键盘按钮,更改按键的值,可用组合键
def Change_Key_B(button):
def on_press(key): # 碰到按键就入列表
if not key in button.key:
button.key.append(key)
button['text'] = button['text'] + str(key) + '+'
def on_release(key): # 某一个键松开,就结束监听,更改按键文本
button['text'] = button['text'][0:-1]
return False
button['text'] = ''
button.key = [] # 初始为空
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
# 监听下回鼠标点击位置
def Give_Mouse(seat):
def on_click(x, y, button, pressed):
if pressed and button == mouse.Button.left: # 碰到按下鼠标左键就更改文本框内容
seat.set(str(x) + ',' + str(y)) # 逗号分割便于之后直接用eval处理
listener.stop()
# 使用事件监听进程,监听到鼠标按下左键,返回位置到文本框
listener = mouse.Listener(on_click=on_click)
listener.start()
# 替代用方法
def end():
pass
# 切换文本类组件的启用/停止
def Changing_Over(t, c):
if c["state"] == 'normal': # 是启用,设为禁用,左键恢复
c['state'] = 'disabled'
c['cursor'] = 'arrow' # 鼠标样式更改
c.bind('<Button-1>', (lambda t=t, entry=c: Changing_Over(t, entry)))
c.bind('<Button-3>', lambda t=t: end())
else: # 是禁用
if c['cursor'] == 'arrow': # 大概率是这个函数设置的禁用
c['state'] = 'normal' # 启用
c['cursor'] = 'xterm' # 鼠标样式更改
# 右键禁用
c.bind('<Button-3>', (lambda t=t, entry=c: Changing_Over(t, entry)))
c.bind('<Button-1>', lambda t=t: end())
# 切换任意组件的启停,不更改鼠标样式
def Changing_All(c):
if c["state"] == 'normal':
c['state'] = 'disabled'
else:
c['state'] = 'normal'
# 监听线程,监听到按下key_start生成并执行ability线程,随后监听key_stop,按下后关闭线程
# 拥有功能终止标记,操控进程终止标记,终止线程
def Monitor(gui):
def on_press(key): # 碰到按键就记录处理
if gui.sparked_stop_tab[0]: # 功能终止
gui.stop_tab[0] = True # 线程也终止
listener.stop() # 结束监听线程
return False
now_key.add(key) # 当前按下的键进入集合
be_tap = 1 # 存在标记
if gui.stop_tab[0]: # 进程没开始
for i in gui.sparked_b.key: # 任何一个开始按键
if not i in now_key: # 没有按下
be_tap = 0 # 不存在,不允许
break
if be_tap: # 检测到所有开始按键/触发键
gui.stop_tab[0] = False # 开始进程
gui.New_ability() # 生成+启动
gui.ability.start()
else: # 进程开始了
if gui.use.get(): # 针对输入text的功能,不会停止
for i in gui.stop_b.key: # 任何一个终止按键
if not i in now_key: # 没有按下
be_tap = 0 # 不存在,不允许
break
if be_tap: # 且按键为结束键
gui.stop_tab[0] = True # 结束进程
def on_release(key):
now_key.discard(key)
now_key = set()
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
# 鼠标gui的功能,模拟点击,
def Analog_Click(gui):
control = Controller() # 创建鼠标控制对象
key = gui.key.get() # 根据键位设置选择点击的键
if key == 0:
key = Button.left
elif key == 1:
key = Button.middle
else:
key = Button.right
for i in range(gui.number.get()): # 反复执行这么多次
if gui.stop_tab[0]: # 进程终止
break
if gui.sparked_stop_tab[0]: # 功能终止
gui.stop_tab[0] = True
return
if gui.click_type.get(): # 如果固定位置点击,移动到固定位置
control.position = eval(gui.click_seat.get())
control.press(key) # 按下
time.sleep(gui.press_time.get()) # 等待到时间后松开
control.release(key) # 松开
if i < gui.number.get() - 1: # 如果是最后一次就不等了
time.sleep(gui.release_time.get()) # 等待到时间后下一轮
if gui.sparked_stop_tab[0]: # 功能终止
return
else:
gui.stop_tab[0] = True # 进程运行结束
return
# 点击启用按钮时,方法
def Mouse_Gui_Start(gui):
def NA(g):
g.ability = Thread(target=lambda g=g: Analog_Click(g))
# 错误处理
try:
click_type = gui.click_type.get()
if click_type == 1:
x, y = eval(gui.click_seat.get())
else:
x, y = 0, 0
except:
tk.messagebox.showwarning(title='警告!',
message='您选择了移动鼠标,但没有正确输入移动坐标点。\n'
'请用x,y格式输入,或直接获取下次鼠标点击位置')
return
if gui.sparked_b['text'] == 'None' or gui.stop_b['text'] == 'None': # 没有设定按键的情况
tk.messagebox.showwarning(title='警告!', message='请设定触发按键和停止按键,以免无法开始或者停止')
return
try:
press_time = gui.press_time.get()
release_time = gui.release_time.get()
if press_time < 0 or release_time < 0:
tk.messagebox.showwarning(title='警告!', message='按下时间和松开时间不能为负。')
return
except:
tk.messagebox.showwarning(title='警告!', message='次数或按下时间和松开时间设置错误。')
return
# 到这里没报错就可以开始进行
gui.start_click_b['state'] = 'disabled' # 禁用启用按钮
gui.start_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.stop_click_b['state'] = 'normal' # 启用停用按钮
gui.stop_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 虽然不禁用也行,但怕你们用的时候乱改报错,禁用比较好
# 没有禁用的,在启用后更改,应该也能生效
gui.click_type_b[0]['state'] = 'disabled'
gui.click_type_b[1]['state'] = 'disabled'
gui.click_entry['state'] = 'disabled'
gui.number_entry['state'] = 'disabled'
gui.press_time_entry['state'] = 'disabled'
gui.release_time_entry['state'] = 'disabled'
gui.sparked_b['state'] = 'disabled'
gui.stop_b['state'] = 'disabled'
gui.sparked_stop_tab = [False] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
gui.New_ability = lambda g=gui: NA(g) # 新建点击线程
gui.sparked = lambda g=gui: Monitor(gui) # 监听线程
gui.sparked() # 启动监听
# 点击停用按钮时,方法
def Mouse_Gui_Stop(gui):
gui.stop_click_b['state'] = 'disabled' # 禁用启用按钮
gui.stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.start_click_b['state'] = 'normal' # 启用停用按钮
gui.start_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 解禁
gui.click_type_b[0]['state'] = 'normal'
gui.click_type_b[1]['state'] = 'normal'
gui.click_entry['state'] = 'normal'
gui.number_entry['state'] = 'normal'
gui.press_time_entry['state'] = 'normal'
gui.release_time_entry['state'] = 'normal'
gui.sparked_b['state'] = 'normal'
gui.stop_b['state'] = 'normal'
gui.sparked_stop_tab = [True] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
# 创建一个鼠标功能GUI
def Add_Mouse():
global data_bar, gui_mouse
gui_mouse.append(tk.LabelFrame(data_bar, text=len(gui_mouse), )) # 添加一个gui
n = len(gui_mouse) - 1 # 当前位置(不想用gui_mouse[-1])
# 左半边界面
gui_mouse[n].l_frame = tk.LabelFrame(gui_mouse[n]) # 左半边框架
gui_mouse[n].l_frame.grid(row=0, column=0, sticky="nsew")
# 第一部分 选择按下的鼠标键
gui_mouse[n].key = tk.IntVar() # 单选按钮的值,用.get()可以取出来,初始0
gui_mouse[n].key_type_b = [ # 键位的单选按钮组,variable控制的变量,value按钮代表的值
tk.Radiobutton(gui_mouse[n].l_frame, text='左键', variable=gui_mouse[n].key, value=0),
tk.Radiobutton(gui_mouse[n].l_frame, text='中键', variable=gui_mouse[n].key, value=1),
tk.Radiobutton(gui_mouse[n].l_frame, text='右键', variable=gui_mouse[n].key, value=2)]
for i in range(3): # 显示一下
gui_mouse[n].key_type_b[i].grid(row=0, column=i, )
# 第二部分 选择鼠标按下的位置
gui_mouse[n].click_type = tk.IntVar() # 位置类型(设定位置/鼠标位置)
gui_mouse[n].click_type_b = [ # 点击位置,选择鼠标直接点击,还是鼠标移动到指定点后点击
tk.Radiobutton(gui_mouse[n].l_frame, text='保持位置', variable=gui_mouse[n].click_type, value=0),
tk.Radiobutton(gui_mouse[n].l_frame, text='移动鼠标', variable=gui_mouse[n].click_type, value=1)]
gui_mouse[n].click_type_b[0].grid(row=1, column=0, )
gui_mouse[n].click_type_b[1].grid(row=2, column=0, )
gui_mouse[n].click_seat = tk.StringVar() # 文本框文本关联变量
gui_mouse[n].click_seat.set('0,0')
gui_mouse[n].click_entry = tk.Entry( # 设定位置文本框
gui_mouse[n].l_frame, exportselection=0, textvariable=gui_mouse[n].click_seat)
gui_mouse[n].click_entry.grid(row=2, column=1, sticky='w', columnspan=2)
gui_mouse[n].click_b = tk.Button( # 获取点击位置按键
gui_mouse[n].l_frame, text='获取下次鼠标点击位置',
command=lambda seat=gui_mouse[n].click_seat: Give_Mouse(seat))
gui_mouse[n].click_b.grid(row=1, column=1, sticky='w', columnspan=2)
# 第三部分 选择功能的触发和停止按键
gui_mouse[n].sparked_label = tk.Label(gui_mouse[n].l_frame, text='触发按键:') # 触发按键前的提示文本
gui_mouse[n].sparked_b = tk.Button(gui_mouse[n].l_frame, text='None', ) # 触发按键本身
gui_mouse[n].sparked_b.key = None
gui_mouse[n].sparked_b['command'] = lambda button=gui_mouse[n].sparked_b: Change_Key_B(button)
gui_mouse[n].stop_label = tk.Label(gui_mouse[n].l_frame, text='停止按键:') # 停止按键前的提示文本
gui_mouse[n].stop_b = tk.Button(gui_mouse[n].l_frame, text='None', ) # 停止按键本身
gui_mouse[n].stop_b.key = None
gui_mouse[n].stop_b['command'] = lambda button=gui_mouse[n].stop_b: Change_Key_B(button)
gui_mouse[n].sparked_label.grid(row=3, column=0, ) # 把这些显示出来,'w'是靠左(西)的意思。
gui_mouse[n].sparked_b.grid(row=3, column=1, sticky='w', columnspan=2)
gui_mouse[n].stop_label.grid(row=4, column=0, )
gui_mouse[n].stop_b.grid(row=4, column=1, sticky='w', columnspan=2)
# 该右半边界面了
gui_mouse[n].r_frame = tk.LabelFrame(gui_mouse[n]) # 右半边框架
gui_mouse[n].r_frame.grid(row=0, column=1, sticky="nsew")
# 第一部分 填入点击次数,按下时间,松开时间属性 右键输入框可以锁定输入
gui_mouse[n].number = tk.IntVar() # 次数变量,控制点击次数,
gui_mouse[n].number.set(1) # 初始给一次
gui_mouse[n].number_label = tk.Label(gui_mouse[n].r_frame, text='次数:') # 次数提示标签
gui_mouse[n].number_entry = tk.Entry( # 设定次数文本框
gui_mouse[n].r_frame, exportselection=0, textvariable=gui_mouse[n].number)
gui_mouse[n].number_unit_label = tk.Label(gui_mouse[n].r_frame, text='次') # 次数单位标签
gui_mouse[n].press_time = tk.DoubleVar() # 按下时间变量,控制按键时间
gui_mouse[n].press_time.set(0.1)
gui_mouse[n].press_time_label = tk.Label(gui_mouse[n].r_frame, text='按下时间:') # 按下时间提示标签
gui_mouse[n].press_time_entry = tk.Entry( # 设定按下时间文本框
gui_mouse[n].r_frame, exportselection=0, textvariable=gui_mouse[n].press_time)
gui_mouse[n].press_time_unit_label = tk.Label(gui_mouse[n].r_frame, text='s') # 按下时间单位标签
gui_mouse[n].release_time = tk.DoubleVar() # 松开时间变量,控制按键间隔时间
gui_mouse[n].release_time.set(0.9)
gui_mouse[n].release_time_label = tk.Label(gui_mouse[n].r_frame, text='松开时间:') # 松开时间提示标签
gui_mouse[n].release_time_entry = tk.Entry( # 设定松开时间文本框
gui_mouse[n].r_frame, exportselection=0, textvariable=gui_mouse[n].release_time)
gui_mouse[n].release_time_unit_label = tk.Label(gui_mouse[n].r_frame, text='s') # 松开时间单位标签
gui_mouse[n].number_label.grid(row=0, column=0, sticky='w') # 给这一堆东西放下来
gui_mouse[n].number_entry.grid(row=0, column=1, sticky='w')
gui_mouse[n].number_unit_label.grid(row=0, column=2, sticky='w')
gui_mouse[n].press_time_label.grid(row=1, column=0, sticky='w')
gui_mouse[n].press_time_entry.grid(row=1, column=1, sticky='w')
gui_mouse[n].press_time_unit_label.grid(row=1, column=2, sticky='w')
gui_mouse[n].release_time_label.grid(row=2, column=0, sticky='w')
gui_mouse[n].release_time_entry.grid(row=2, column=1, sticky='w')
gui_mouse[n].release_time_unit_label.grid(row=2, column=2, sticky='w')
# 第二部分
# 关键的启动和停止按钮
gui_mouse[n].start_click_b = tk.Button(gui_mouse[n].r_frame, text='启用', )
gui_mouse[n].stop_click_b = tk.Button(gui_mouse[n].r_frame, text='停用', )
gui_mouse[n].stop_click_b['state'] = 'disabled' # 初始,停用按钮为禁用
gui_mouse[n].stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui_mouse[n].start_click_b['command'] = lambda gui=gui_mouse[n]: Mouse_Gui_Start(gui)
gui_mouse[n].stop_click_b['command'] = lambda gui=gui_mouse[n]: Mouse_Gui_Stop(gui)
gui_mouse[n].start_click_b.grid(row=3, column=0, )
gui_mouse[n].stop_click_b.grid(row=3, column=1, )
# 第三部分,删除按钮
gui_mouse[n].delete = tk.Button(gui_mouse[n].r_frame, text='删除', )
gui_mouse[n].delete['command'] = lambda gui_gather=gui_mouse, gui=gui_mouse[n]: Delete_gui(gui_gather, gui)
gui_mouse[n].delete.grid(row=4, column=1, )
# 给所有文本框绑定一下点击启/禁用功能
t = 0 # 盖住第一个点击位置的调用
gui_mouse[n].click_entry.bind('<Button-3>',
(lambda t=t, entry=gui_mouse[n].click_entry: Changing_Over(t, entry)))
gui_mouse[n].number_entry.bind('<Button-3>',
(lambda t=t, entry=gui_mouse[n].number_entry: Changing_Over(t, entry)))
gui_mouse[n].press_time_entry.bind('<Button-3>',
(lambda t=t, entry=gui_mouse[n].press_time_entry: Changing_Over(t, entry)))
gui_mouse[n].release_time_entry.bind('<Button-3>',
(lambda t=t, entry=gui_mouse[n].release_time_entry: Changing_Over(t, entry)))
# 放缩控制
gui_mouse[n].columnconfigure(0, weight=1) # column为0,缩放比为1(列)
gui_mouse[n].columnconfigure(1, weight=1) # column为0,缩放比为1
for i in range(5):
gui_mouse[n].l_frame.rowconfigure(i, weight=1)
for i in range(3):
gui_mouse[n].l_frame.columnconfigure(i, weight=1)
gui_mouse[n].use = tk.IntVar() # 用于兼容键盘
gui_mouse[n].use.set(1)
Common_Mouse() # 最后刷新一下gui界面
# 键盘gui的功能,模拟按键或者模拟输入
def Analog_Key(gui):
k = keyboard.Controller() # 创建键盘控制对象
if gui.use.get(): # 是1
for i in range(gui.number.get()): # 反复执行这么多次
if gui.stop_tab[0]: # 进程终止
break
if gui.sparked_stop_tab[0]: # 功能终止
gui.stop_tab[0] = True
return
for key in gui.presskey_b.key:
k.press(key) # 按下
time.sleep(gui.press_time.get()) # 等待到时间后松开
for key in gui.presskey_b.key:
k.release(key) # 松开
if i < gui.number.get() - 1: # 如果是最后一次就不等了
time.sleep(gui.release_time.get()) # 等待到时间后下一轮
else: # 0,单纯输出文本框的内容就行
k.type(gui.l_frame_1.text.get('0.0', 'end'))
if gui.sparked_stop_tab[0]: # 功能终止
return
else:
gui.stop_tab[0] = True # 进程运行结束
return
# 点击启用按钮时,方法
def Fingerboard_Gui_Start(gui):
def NA(g): # 这里不判断操作类型,留到使用时再判断
g.ability = Thread(target=lambda g=g: Analog_Key(g))
# 错误处理
if gui.sparked_b['text'] == 'None' or gui.stop_b['text'] == 'None': # 没有设定按键的情况
tk.messagebox.showwarning(title='警告!', message='请设定触发按键和停止按键,以免无法开始或者停止')
return
if gui.use.get():
try:
press_time = gui.press_time.get()
release_time = gui.release_time.get()
if press_time < 0 or release_time < 0:
tk.messagebox.showwarning(title='警告!', message='按下时间和松开时间不能为负。')
return
except:
tk.messagebox.showwarning(title='警告!', message='次数或按下时间和松开时间设置错误。')
return
if gui.presskey_b['text'] == 'None':
tk.messagebox.showwarning(title='警告!', message='请设定需要按下的按钮或组合键')
return
# 到这里没报错就可以开始进行
gui.start_click_b['state'] = 'disabled' # 禁用启用按钮
gui.start_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.stop_click_b['state'] = 'normal' # 启用停用按钮
gui.stop_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 基本与鼠标那边相同····甚至完全可以复用····这么区分清楚些(自我安慰)
# 虽然不禁用也行,但怕你们用的时候乱改报错,禁用比较好
# 没有禁用的,在启用后更改,应该也能生效
gui.use_type_b[0]['state'] = 'disabled'
gui.use_type_b[1]['state'] = 'disabled'
gui.number_entry['state'] = 'disabled'
gui.press_time_entry['state'] = 'disabled'
gui.release_time_entry['state'] = 'disabled'
gui.sparked_b['state'] = 'disabled'
gui.stop_b['state'] = 'disabled'
gui.sparked_stop_tab = [False] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
gui.New_ability = lambda g=gui: NA(g) # 新建按下线程
gui.sparked = lambda g=gui: Monitor(gui) # 监听线程
gui.sparked() # 启动监听
# 点击停用按钮时,方法
def Fingerboard_Gui_Stop(gui):
gui.stop_click_b['state'] = 'disabled' # 禁用启用按钮
gui.stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.start_click_b['state'] = 'normal' # 启用停用按钮
gui.start_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 启用单选按钮和文本框
gui.use_type_b[0]['state'] = 'normal'
gui.use_type_b[1]['state'] = 'normal'
gui.number_entry['state'] = 'normal'
gui.press_time_entry['state'] = 'normal'
gui.release_time_entry['state'] = 'normal'
gui.sparked_b['state'] = 'normal'
gui.stop_b['state'] = 'normal'
gui.sparked_stop_tab = [True] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
# 通过单选按钮,改变左边显示的框架
def Chenge_Fingerboard_l(gui):
if gui.use.get(): # 选择的是第二个 0/1
gui.l_frame_1.grid_forget() # 取消显示1
gui.l_frame_2.grid(row=0, column=0, sticky="nsew") # 显示2
else: # 选择的是第一个
gui.l_frame_1.grid(row=0, column=0, sticky="nsew") # 显示1
gui.l_frame_2.grid_forget() # 取消显示2
# 创建一个键盘功能GUI
def Add_Fingerboard():
global data_bar, gui_fingerboard
gui_fingerboard.append(tk.LabelFrame(data_bar, text=len(gui_fingerboard), )) # 添加一个gui
n = len(gui_fingerboard) - 1 # 当前位置(不想用gui_fingerboard[-1])
# 先搞右半边界面,因为右半边选项会修改左半边界面
gui_fingerboard[n].r_frame = tk.LabelFrame(gui_fingerboard[n]) # 右半边框架
gui_fingerboard[n].r_frame.grid(row=0, column=1, sticky="nsew")
# 第一部分
gui_fingerboard[n].use = tk.IntVar() # 单选按钮的值,用.get()可以取出来,初始0
gui_fingerboard[n].use_type_b = [ # 功能选项的单选按钮组,variable控制的变量,value按钮代表的值
tk.Radiobutton(gui_fingerboard[n].r_frame, text='输入字符串', variable=gui_fingerboard[n].use,
value=0, command=lambda gui=gui_fingerboard[n]: Chenge_Fingerboard_l(gui)),
tk.Radiobutton(gui_fingerboard[n].r_frame, text='按下固定键', variable=gui_fingerboard[n].use,
value=1, command=lambda gui=gui_fingerboard[n]: Chenge_Fingerboard_l(gui))]
for i in range(2): # 显示一下
gui_fingerboard[-1].use_type_b[i].grid(row=0, column=i, )
# 第二部分 选择功能的触发键和停止键
gui_fingerboard[n].sparked_label = tk.Label(gui_fingerboard[n].r_frame, text='触发按键:') # 触发按键前的提示文本
gui_fingerboard[n].sparked_b = tk.Button(gui_fingerboard[n].r_frame, text='None', ) # 触发按键本身
gui_fingerboard[n].sparked_b.key = None
gui_fingerboard[n].sparked_b['command'] = lambda button=gui_fingerboard[n].sparked_b: Change_Key_B(button)
gui_fingerboard[n].stop_label = tk.Label(gui_fingerboard[n].r_frame, text='停止按键:') # 停止按键前的提示文本
gui_fingerboard[n].stop_b = tk.Button(gui_fingerboard[n].r_frame, text='None', ) # 停止按键本身
gui_fingerboard[n].stop_b.key = None
gui_fingerboard[n].stop_b['command'] = lambda button=gui_fingerboard[n].stop_b: Change_Key_B(button)
gui_fingerboard[n].sparked_label.grid(row=1, column=0, ) # 把这些显示出来,'w'是靠左(西)的意思。
gui_fingerboard[n].sparked_b.grid(row=1, column=1, sticky='w', columnspan=2)
gui_fingerboard[n].stop_label.grid(row=2, column=0, )
gui_fingerboard[n].stop_b.grid(row=2, column=1, sticky='w', columnspan=2)
# 第三部分,启停按钮
gui_fingerboard[n].start_click_b = tk.Button(gui_fingerboard[n].r_frame, text='启用', )
gui_fingerboard[n].stop_click_b = tk.Button(gui_fingerboard[n].r_frame, text='停用', )
gui_fingerboard[n].stop_click_b['state'] = 'disabled' # 初始,停用按钮为禁用
gui_fingerboard[n].stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui_fingerboard[n].start_click_b['command'] = lambda gui=gui_fingerboard[n]: Fingerboard_Gui_Start(gui)
gui_fingerboard[n].stop_click_b['command'] = lambda gui=gui_fingerboard[n]: Fingerboard_Gui_Stop(gui)
gui_fingerboard[n].start_click_b.grid(row=3, column=0, )
gui_fingerboard[n].stop_click_b.grid(row=3, column=1, sticky='w', )
# 第四部分,删除按钮
gui_fingerboard[n].delete = tk.Button(gui_fingerboard[n].r_frame, text='删除', )
gui_fingerboard[n].delete['command'] = lambda gui_gather=gui_fingerboard, gui=gui_fingerboard[n]: Delete_gui(
gui_gather, gui)
gui_fingerboard[n].delete.grid(row=4, column=1, sticky='w', )
# 左半边框架
gui_fingerboard[n].l_frame_1 = tk.LabelFrame(gui_fingerboard[n]) # 右半边框架 输入字符串
gui_fingerboard[n].l_frame_1.grid(row=0, column=0, sticky="nsew") # 初始是0,显示1
gui_fingerboard[n].l_frame_2 = tk.LabelFrame(gui_fingerboard[n]) # 右半边框架 按下固定按钮
# gui_fingerboard[n].l_frame_2.grid(row=0, column=0, sticky="nsew")
# 选择0时的左半边框架(只包含一个文本框(带滚动条)和一个标签)
gui_fingerboard[n].l_frame_1.text_l = tk.Label(gui_fingerboard[n].l_frame_1, text='输入内容') # 标签提示
gui_fingerboard[n].l_frame_1.scrollbar_x = tk.Scrollbar(gui_fingerboard[n].l_frame_1, orient=tk.HORIZONTAL) # 滚动条x
gui_fingerboard[n].l_frame_1.scrollbar_y = tk.Scrollbar(gui_fingerboard[n].l_frame_1, orient=tk.VERTICAL) # 滚动条y
gui_fingerboard[n].l_frame_1.text = tk.Text(gui_fingerboard[n].l_frame_1, width=20, height=8, wrap=tk.NONE, # 文本框
xscrollcommand=gui_fingerboard[n].l_frame_1.scrollbar_x.set,
yscrollcommand=gui_fingerboard[n].l_frame_1.scrollbar_y.set, )
# 将他们显示出来
gui_fingerboard[n].l_frame_1.text_l.pack()
gui_fingerboard[n].l_frame_1.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X) # 靠下,拉满x
gui_fingerboard[n].l_frame_1.scrollbar_x.config(command=gui_fingerboard[n].l_frame_1.text.xview)
gui_fingerboard[n].l_frame_1.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y) # 靠右,拉满y
gui_fingerboard[n].l_frame_1.scrollbar_y.config(command=gui_fingerboard[n].l_frame_1.text.yview)
gui_fingerboard[n].l_frame_1.text.pack(fill=tk.BOTH)
# 选择1时的左半边框架(包含按键选择,按下次数,按下时间,松开时间)
gui_fingerboard[n].presskey_label = tk.Label(gui_fingerboard[n].l_frame_2, text='按下按键:') # 需要按下按键前的提示文本
gui_fingerboard[n].presskey_b = tk.Button(gui_fingerboard[n].l_frame_2, text='None', ) # 需要按下按键本身
gui_fingerboard[n].presskey_b.key = None
gui_fingerboard[n].presskey_b['command'] = lambda button=gui_fingerboard[n].presskey_b: Change_Key_B(button)
gui_fingerboard[n].number = tk.IntVar() # 次数变量,控制点击次数,
gui_fingerboard[n].number.set(1) # 初始给一次
gui_fingerboard[n].number_label = tk.Label(gui_fingerboard[n].l_frame_2, text='次数:') # 次数提示标签
gui_fingerboard[n].number_entry = tk.Entry( # 设定次数文本框
gui_fingerboard[n].l_frame_2, exportselection=0, textvariable=gui_fingerboard[n].number)
gui_fingerboard[n].number_unit_label = tk.Label(gui_fingerboard[n].l_frame_2, text='次') # 次数单位标签
gui_fingerboard[n].press_time = tk.DoubleVar() # 按下时间变量,控制按键时间
gui_fingerboard[n].press_time.set(0.1)
gui_fingerboard[n].press_time_label = tk.Label(gui_fingerboard[n].l_frame_2, text='按下时间:') # 按下时间提示标签
gui_fingerboard[n].press_time_entry = tk.Entry( # 设定按下时间文本框
gui_fingerboard[n].l_frame_2, exportselection=0, textvariable=gui_fingerboard[n].press_time)
gui_fingerboard[n].press_time_unit_label = tk.Label(gui_fingerboard[n].l_frame_2, text='s') # 按下时间单位标签
gui_fingerboard[n].release_time = tk.DoubleVar() # 松开时间变量,控制按键间隔时间
gui_fingerboard[n].release_time.set(0.9)
gui_fingerboard[n].release_time_label = tk.Label(gui_fingerboard[n].l_frame_2, text='松开时间:') # 松开时间提示标签
gui_fingerboard[n].release_time_entry = tk.Entry( # 设定松开时间文本框
gui_fingerboard[n].l_frame_2, exportselection=0, textvariable=gui_fingerboard[n].release_time)
gui_fingerboard[n].release_time_unit_label = tk.Label(gui_fingerboard[n].l_frame_2, text='s') # 松开时间单位标签
gui_fingerboard[n].presskey_label.grid(row=0, column=0, ) # 给这一堆东西放下来
gui_fingerboard[n].presskey_b.grid(row=0, column=1, sticky='w', columnspan=2)
gui_fingerboard[n].number_label.grid(row=1, column=0, sticky='w')
gui_fingerboard[n].number_entry.grid(row=1, column=1, sticky='w')
gui_fingerboard[n].number_unit_label.grid(row=1, column=2, sticky='w')
gui_fingerboard[n].press_time_label.grid(row=2, column=0, sticky='w')
gui_fingerboard[n].press_time_entry.grid(row=2, column=1, sticky='w')
gui_fingerboard[n].press_time_unit_label.grid(row=2, column=2, sticky='w')
gui_fingerboard[n].release_time_label.grid(row=3, column=0, sticky='w')
gui_fingerboard[n].release_time_entry.grid(row=3, column=1, sticky='w')
gui_fingerboard[n].release_time_unit_label.grid(row=3, column=2, sticky='w')
# 给所有文本框绑定一下点击启/禁用功能
t = 0 # 盖住第一个点击位置的调用
gui_fingerboard[n].l_frame_1.text.bind('<Button-3>', (
lambda t=t, entry=gui_fingerboard[n].l_frame_1.text: Changing_Over(t, entry)))
gui_fingerboard[n].number_entry.bind('<Button-3>', (
lambda t=t, entry=gui_fingerboard[n].number_entry: Changing_Over(t, entry)))
gui_fingerboard[n].press_time_entry.bind('<Button-3>', (
lambda t=t, entry=gui_fingerboard[n].press_time_entry: Changing_Over(t, entry)))
gui_fingerboard[n].release_time_entry.bind('<Button-3>', (
lambda t=t, entry=gui_fingerboard[n].release_time_entry: Changing_Over(t, entry)))
# 放缩控制
gui_fingerboard[n].columnconfigure(0, weight=1) # column为0,缩放比为1(列)
gui_fingerboard[n].columnconfigure(1, weight=1) # column为0,缩放比为1
for i in range(5):
gui_fingerboard[n].l_frame_1.rowconfigure(i, weight=1)
gui_fingerboard[n].l_frame_2.rowconfigure(i, weight=1)
gui_fingerboard[n].r_frame.rowconfigure(i, weight=1)
for i in range(3):
gui_fingerboard[n].l_frame_1.columnconfigure(i, weight=1)
gui_fingerboard[n].l_frame_2.columnconfigure(i, weight=1)
gui_fingerboard[n].r_frame.columnconfigure(i, weight=1)
Common_Fingerboard() # 最后刷新一下gui界面
# 录制的数据结构:[[鼠标],[键盘]]
# 鼠标 = {鼠标节点},{鼠标节点},{鼠标节点},
# 鼠标节点 = time: 按下的系统时间, sleep_time: 距离上一次 操作的时间
# kind: 操作类型(0:初始无操作,1:移动 2:按下 3:滚动)
# x,y: 鼠标操作的位置, button: 按下的键 pressed: 点击或松开
# dx,dy:鼠标滚动坐标 类型往后的不一定都有
# 键盘节点 = time: 按下的系统时间, sleep_time: 距离上一次 操作的时间
# kind: 操作类型(0:初始无操作,1:按下 2:松开)
# key: 操作的按键
# 录制指令
def Action_Record(g):
# 录制鼠标
def Record_Mouse(g):
def l_stop(): # 终止判断
if g.sparked_stop_tab[0]: # 功能终止
g.stop_tab[0] = True # 线程终止
listener_mouse.stop() # 结束监听
return True
if g.stop_tab[0]: # 进程终止
listener_mouse.stop() # 结束监听
return True
return False
def on_move(x, y): # 记录鼠标移动
if l_stop(): # 终止判断
return False
g.record_data[0].append(
{'kind': 1, 'time': time.time(), 'x': x, 'y': y})
g.record_data[0][-1]['sleep_time'] = g.record_data[0][-1]['time'] - g.record_data[0][-2]['time']
def on_click(x, y, button, pressed): # 记录鼠标点击
g.record_data[0].append(
{'kind': 2, 'time': time.time(), 'x': x, 'y': y, 'button': button, 'pressed': pressed})
g.record_data[0][-1]['sleep_time'] = g.record_data[0][-1]['time'] - g.record_data[0][-2]['time']
def on_scroll(x, y, dx, dy): # 记录鼠标滚动
if l_stop(): # 终止判断
return False
g.record_data[0].append(
{'kind': 3, 'time': time.time(), 'x': x, 'y': y, 'dx': dx, 'dy': dy})
g.record_data[0][-1]['sleep_time'] = g.record_data[0][-1]['time'] - g.record_data[0][-2]['time']
listener_mouse = mouse.Listener(on_move, on_click, on_scroll)
listener_mouse.start()
# 录制键盘
def Record_Keyboard(g):
def l_stop(): # 终止判断
if g.sparked_stop_tab[0]: # 功能终止
g.stop_tab[0] = True # 线程终止
listener_keyboard.stop() # 结束监听
return True
if g.stop_tab[0]: # 进程终止
listener_keyboard.stop() # 结束监听
return True
return False
def on_press(key): # 按下按键
if l_stop(): # 终止判断
return False
g.record_data[1].append({'kind': 1, 'time': time.time(), 'key': key})
g.record_data[1][-1]['sleep_time'] = g.record_data[1][-1]['time'] - g.record_data[1][-2]['time']
def on_release(key): # 松开按键
g.record_data[1].append({'kind': 2, 'time': time.time(), 'key': key})
g.record_data[1][-1]['sleep_time'] = g.record_data[1][-1]['time'] - g.record_data[1][-2]['time']
listener_keyboard = keyboard.Listener(on_press=on_press, on_release=on_release)
listener_keyboard.start()
g.record_data.clear() # 删除上一回的录制
g.record_data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存鼠标
g.record_data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存键盘
if not g.record_use.get() == 1: # 录制鼠标
Record_Mouse(g)
if not g.record_use.get() == 0: # 录制键盘
Record_Keyboard(g)
return
# 点击左半边录制启用按钮时,方法
def Transcribe_Gui_Start_l(gui):
def NA(g): # 这里不判断操作类型,留到使用时再判断
g.ability = Thread(target=lambda g=g: Action_Record(g))
# 错误处理
if gui.sparked_b['text'] == 'None' or gui.stop_b['text'] == 'None': # 没有设定按键的情况
tk.messagebox.showwarning(title='警告!', message='请设定录制开始和录制停止按键,以免无法开始或者停止')
return
# 到这里没报错就可以开始进行
gui.start_click_b['state'] = 'disabled' # 禁用启用按钮
gui.start_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.stop_click_b['state'] = 'normal' # 启用停用按钮
gui.stop_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 基本与鼠标那边相同····甚至完全可以复用····这么区分清楚些(自我安慰)
# 虽然不禁用也行,但怕你们用的时候乱改报错,禁用比较好
# 没有禁用右半边,但是还是劝正常操作.
gui.sparked_b['state'] = 'disabled'
gui.stop_b['state'] = 'disabled'
for i in range(3):
gui.record_type_b[i]['state'] = 'disabled'
gui.sparked_stop_tab = [False] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
gui.New_ability = lambda g=gui: NA(g) # 新建按下线程
gui.sparked = lambda g=gui: Monitor(gui) # 监听线程
gui.sparked() # 启动监听
# 点击左半边录制停用按钮时,方法
def Transcribe_Gui_Stop_l(gui):
gui.stop_click_b['state'] = 'disabled' # 禁用启用按钮
gui.stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.start_click_b['state'] = 'normal' # 启用停用按钮
gui.start_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 启用
gui.sparked_b['state'] = 'normal'
gui.stop_b['state'] = 'normal'
for i in range(3):
gui.record_type_b[i]['state'] = 'normal'
gui.sparked_stop_tab = [True] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
# 录制重播方法
def Rebroadcast(g):
def Rebroadcast_Move(): # 重播鼠标
control = Controller() # 创建鼠标控制对象
for i in g.l_frame.record_data[0]:
if g.sparked_stop_tab[0]: # 功能终止
g.stop_tab[0] = True
break
if g.stop_tab[0]: # 线程终止
break
time.sleep(i['sleep_time']) # 睡
if i['kind'] != 0: # 不为0,有移动操作
control.position = (i['x'], i['y'])
if i['kind'] == 2: # 点击
if i['pressed']:
control.press(i['button'])
else:
control.release(i['button'])
elif i['kind'] == 3: # 滚动
control.scroll(i['dx'], i['dy'])
def Rebroadcast_Keyboard(): # 重播键盘
k = keyboard.Controller() # 创建键盘控制对象
for i in g.l_frame.record_data[1]:
if g.sparked_stop_tab[0]:
g.stop_tab[0] = True
break
if g.stop_tab[0]:
break
time.sleep(i['sleep_time'])
if i['kind'] == 1:
k.press(i['key'])
elif i['kind'] == 2:
k.release(i['key'])
rebroadcast_move = Thread(target=Rebroadcast_Move)
rebroadcast_keyboard = Thread(target=Rebroadcast_Keyboard)
rebroadcast_move.start()
rebroadcast_keyboard.start()
rebroadcast_move.join()
rebroadcast_keyboard.join()
g.stop_tab[0] = True
# 点击录制重播启用按钮时,方法
def Transcribe_Gui_Start(gui):
def NA(g): # 录制文件重播
g.ability = Thread(target=lambda g=g: Rebroadcast(g))
if not gui.l_frame.sparked_stop_tab[0]:
tk.messagebox.showwarning(title='警告!', message='录制功能正在开启,请停止录制后再使用')
return
if gui.sparked_b['text'] == 'None' or gui.stop_b['text'] == 'None': # 没有设定按键的情况
tk.messagebox.showwarning(title='警告!', message='请设定录制开始和录制停止按键,以免无法开始或者停止')
return
gui.start_click_b['state'] = 'disabled' # 禁用启用按钮
gui.start_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.stop_click_b['state'] = 'normal' # 启用停用按钮
gui.stop_click_b['cursor'] = 'hand2' # 鼠标样式更改
gui.l_frame.start_click_b['state'] = 'disabled'
gui.record_edit['state'] = 'disabled'
gui.record_delete['state'] = 'disabled'
gui.sparked_b['state'] = 'disabled'
gui.stop_b['state'] = 'disabled'
gui.sparked_stop_tab = [False] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
gui.New_ability = lambda g=gui: NA(g) # 新建按下线程
gui.sparked = lambda g=gui: Monitor(gui) # 监听线程
gui.sparked() # 启动监听
# 点击录制重播停用按钮时,方法
def Transcribe_Gui_Stop(gui):
gui.stop_click_b['state'] = 'disabled' # 禁用启用按钮
gui.stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui.start_click_b['state'] = 'normal' # 启用停用按钮
gui.start_click_b['cursor'] = 'hand2' # 鼠标样式更改
# 启用
gui.l_frame.start_click_b['state'] = 'normal'
gui.record_edit['state'] = 'normal'
gui.record_delete['state'] = 'normal'
gui.sparked_b['state'] = 'normal'
gui.stop_b['state'] = 'normal'
gui.sparked_stop_tab = [True] # 功能终止标记
gui.stop_tab = [True] # 点击进程终止标记
# 创建一个录制功能GUI
def Add_Transcribe():
global data_bar, gui_transcribe
gui_transcribe.append(tk.LabelFrame(data_bar, text=len(gui_transcribe), )) # 添加一个gui
n = len(gui_transcribe) - 1 # 当前位置(不想用gui_transcribe[-1])
# 左半边界面
gui_transcribe[n].l_frame = tk.LabelFrame(gui_transcribe[n]) # 左半边框架
gui_transcribe[n].l_frame.grid(row=0, column=0, sticky="nsew")
gui_transcribe[n].l_frame.record_data = [] # 录制的数据保存在这里
gui_transcribe[n].l_frame.record_data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存鼠标
gui_transcribe[n].l_frame.record_data.append([{'kind': 0, 'time': time.time(), 'sleep_time': 0, }]) # 保存键盘
# 第一部分,录制选项
gui_transcribe[n].l_frame.record_use = tk.IntVar()
gui_transcribe[n].l_frame.record_type_b = [
tk.Radiobutton(gui_transcribe[n].l_frame, text='仅录鼠标', variable=gui_transcribe[n].l_frame.record_use, value=0),
tk.Radiobutton(gui_transcribe[n].l_frame, text='仅录键盘', variable=gui_transcribe[n].l_frame.record_use, value=1),
tk.Radiobutton(gui_transcribe[n].l_frame, text='两者都录', variable=gui_transcribe[n].l_frame.record_use, value=2)]
for i in range(3):
gui_transcribe[n].l_frame.record_type_b[i].grid(row=0, column=i, )
# 第二部分,录制开始和停止按钮
gui_transcribe[n].l_frame.sparked_label = tk.Label(gui_transcribe[n].l_frame, text='开始录制:') # 触发按键前的提示文本
gui_transcribe[n].l_frame.sparked_b = tk.Button(gui_transcribe[n].l_frame, text='None', ) # 触发按键本身
gui_transcribe[n].l_frame.sparked_b.key = None
gui_transcribe[n].l_frame.sparked_b['command'] = lambda button=gui_transcribe[n].l_frame.sparked_b: Change_Key_B(
button)
gui_transcribe[n].l_frame.stop_label = tk.Label(gui_transcribe[n].l_frame, text='停止录制:') # 停止按键前的提示文本
gui_transcribe[n].l_frame.stop_b = tk.Button(gui_transcribe[n].l_frame, text='None', ) # 停止按键本身
gui_transcribe[n].l_frame.stop_b.key = None
gui_transcribe[n].l_frame.stop_b['command'] = lambda button=gui_transcribe[n].l_frame.stop_b: Change_Key_B(button)
gui_transcribe[n].l_frame.sparked_label.grid(row=1, column=0, ) # 把这些显示出来,'w'是靠左(西)的意思。
gui_transcribe[n].l_frame.sparked_b.grid(row=1, column=1, sticky='w', columnspan=2)
gui_transcribe[n].l_frame.stop_label.grid(row=2, column=0, )
gui_transcribe[n].l_frame.stop_b.grid(row=2, column=1, sticky='w', columnspan=2)
# 第三部分,录制的启停按钮
gui_transcribe[n].l_frame.start_click_b = tk.Button(gui_transcribe[n].l_frame, text='启用录制', )
gui_transcribe[n].l_frame.stop_click_b = tk.Button(gui_transcribe[n].l_frame, text='停用录制', )
gui_transcribe[n].l_frame.stop_click_b['state'] = 'disabled' # 初始,停用按钮为禁用
gui_transcribe[n].l_frame.stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui_transcribe[n].l_frame.start_click_b['command'] = \
lambda gui=gui_transcribe[n].l_frame: Transcribe_Gui_Start_l(gui)
gui_transcribe[n].l_frame.stop_click_b['command'] = \
lambda gui=gui_transcribe[n].l_frame: Transcribe_Gui_Stop_l(gui)
gui_transcribe[n].l_frame.start_click_b.grid(row=3, column=0, )
gui_transcribe[n].l_frame.stop_click_b.grid(row=3, column=1, )
# 该右半边界面了
gui_transcribe[n].r_frame = tk.LabelFrame(gui_transcribe[n]) # 右半边框架
gui_transcribe[n].r_frame.grid(row=0, column=1, sticky="nsew")
# 第一部分,录制文件编辑和删除按钮
gui_transcribe[n].record_edit = tk.Button(gui_transcribe[n].r_frame, text='录制编辑', )
gui_transcribe[n].record_delete = tk.Button(gui_transcribe[n].r_frame, text='录制删除', )
gui_transcribe[n].record_edit['command'] = lambda data=gui_transcribe[n].l_frame.record_data: Record_Edit(data)
gui_transcribe[n].record_delete['command'] = lambda data=gui_transcribe[n].l_frame.record_data: Record_Delete(data)
gui_transcribe[n].record_edit.grid(row=0, column=0, sticky="nsew")
gui_transcribe[n].record_delete.grid(row=0, column=1, sticky="nsew")
# 第二部分,开始和停止按键设置
gui_transcribe[n].sparked_label = tk.Label(gui_transcribe[n].r_frame, text='触发按键:') # 触发按键前的提示文本
gui_transcribe[n].sparked_b = tk.Button(gui_transcribe[n].r_frame, text='None', ) # 触发按键本身
gui_transcribe[n].sparked_b.key = None
gui_transcribe[n].sparked_b['command'] = lambda button=gui_transcribe[n].sparked_b: Change_Key_B(button)
gui_transcribe[n].stop_label = tk.Label(gui_transcribe[n].r_frame, text='停止按键:') # 停止按键前的提示文本
gui_transcribe[n].stop_b = tk.Button(gui_transcribe[n].r_frame, text='None', ) # 停止按键本身
gui_transcribe[n].stop_b.key = None
gui_transcribe[n].stop_b['command'] = lambda button=gui_transcribe[n].stop_b: Change_Key_B(button)
gui_transcribe[n].sparked_label.grid(row=1, column=0, ) # 把这些显示出来,'w'是靠左(西)的意思。
gui_transcribe[n].sparked_b.grid(row=1, column=1, sticky='w', columnspan=2)
gui_transcribe[n].stop_label.grid(row=2, column=0, )
gui_transcribe[n].stop_b.grid(row=2, column=1, sticky='w', columnspan=2)
# 第三部分,启停按钮
gui_transcribe[n].start_click_b = tk.Button(gui_transcribe[n].r_frame, text='启用', )
gui_transcribe[n].stop_click_b = tk.Button(gui_transcribe[n].r_frame, text='停用', )
gui_transcribe[n].stop_click_b['state'] = 'disabled' # 初始,停用按钮为禁用
gui_transcribe[n].stop_click_b['cursor'] = 'arrow' # 鼠标样式更改
gui_transcribe[n].start_click_b['command'] = lambda gui=gui_transcribe[n]: Transcribe_Gui_Start(gui)
gui_transcribe[n].stop_click_b['command'] = lambda gui=gui_transcribe[n]: Transcribe_Gui_Stop(gui)
gui_transcribe[n].start_click_b.grid(row=3, column=0, )
gui_transcribe[n].stop_click_b.grid(row=3, column=1, sticky='w', )
# 第四部分,删除按钮
gui_transcribe[n].delete = tk.Button(gui_transcribe[n].r_frame, text='删除', )
gui_transcribe[n].delete['command'] = lambda gui_gather=gui_transcribe, gui=gui_transcribe[n]: Delete_gui(
gui_gather, gui)
gui_transcribe[n].delete.grid(row=4, column=1, sticky='w', )
# 放缩控制
gui_transcribe[n].columnconfigure(0, weight=1) # column为0,缩放比为1(列)
gui_transcribe[n].columnconfigure(1, weight=1) # column为0,缩放比为1
for i in range(4):
gui_transcribe[n].l_frame.rowconfigure(i, weight=1)
gui_transcribe[n].r_frame.rowconfigure(i, weight=1)
for i in range(3):
gui_transcribe[n].l_frame.columnconfigure(i, weight=1)
gui_transcribe[n].l_frame.sparked_stop_tab = [True] # 功能终止标记
gui_transcribe[n].l_frame.stop_tab = [True] # 点击进程终止标记
gui_transcribe[n].r_frame.columnconfigure(0, weight=1)
gui_transcribe[n].r_frame.columnconfigure(1, weight=1)
gui_transcribe[n].l_frame.use = tk.IntVar() # 用于兼容键盘
gui_transcribe[n].l_frame.use.set(2)
gui_transcribe[n].use = tk.IntVar() # 用于兼容键盘
gui_transcribe[n].use.set(2)
Common_Transcribe() # 最后刷新一下gui界面
# 由按钮控制的上翻页
def Gui_UP():
global works, seat_mouse, seat_fingerboard, seat_transcribe
if works == 'mouse': # 判断当前类型
if seat_mouse > 0: # 看一眼长度是否越界
seat_mouse -= 1 # 修改位置
Common_Mouse() # 重新启动
elif works == 'fingerboard':
if seat_fingerboard > 0:
seat_fingerboard -= 1
Common_Fingerboard()
elif works == 'transcribe':
if seat_transcribe > 0:
seat_transcribe -= 1
Common_Transcribe()
# 按钮控制下翻页
def Gui_DOWN():
global works, seat_mouse, seat_fingerboard, seat_transcribe
global gui_mouse, gui_fingerboard, gui_transcribe
if works == 'mouse': # 判断当前类型
if seat_mouse < len(gui_mouse) - 1: # 看一眼长度是否越界
seat_mouse += 1 # 修改位置
Common_Mouse() # 重新启动
elif works == 'fingerboard':
if seat_fingerboard < len(gui_fingerboard) - 1:
seat_fingerboard += 1
Common_Fingerboard()
elif works == 'transcribe':
if seat_transcribe < len(gui_transcribe) - 1:
seat_transcribe += 1
Common_Transcribe()
# 重置数据栏
def Resetting_Data_Bar():
global data_bar
# 遍历所有数据栏组件,取消显示
for i in data_bar.grid_slaves():
i.grid_forget()
# 普通模式功能按钮-鼠标
def Common_Mouse():
global gui_mouse, data_bar, gui_data, seat_mouse, works, up_button, down_button
Resetting_Data_Bar()
works = 'mouse'
up_button.grid(row=0, )
down_button.grid(row=4, )
i = 0
while i < 3: # 将三个gui放在数据框中,如果没有就放空框
if i + seat_mouse >= len(gui_mouse):
gui_data[i].grid(row=i + 1, sticky="nsew")
else:
gui_mouse[i + seat_mouse].grid(row=i + 1, sticky="nsew")
i += 1
# 普通模式功能按钮-键盘
def Common_Fingerboard():
global gui_fingerboard, gui_data, seat_fingerboard, works, up_button, down_button
Resetting_Data_Bar()
works = 'fingerboard'
up_button.grid(row=0, )
down_button.grid(row=4, )
i = 0
while i < 3: # 将三个gui放在数据框中,如果没有就放空框
if i + seat_fingerboard >= len(gui_fingerboard):
gui_data[i].grid(row=i + 1, sticky="nsew")
else:
gui_fingerboard[i + seat_fingerboard].grid(row=i + 1, sticky="nsew")
i += 1
# 普通模式功能按钮-录制
def Common_Transcribe():
global gui_transcribe, gui_data, seat_transcribe, works, up_button, down_button
Resetting_Data_Bar()
works = 'transcribe'
up_button.grid(row=0, )
down_button.grid(row=4, )
i = 0
while i < 3: # 将三个gui放在数据框中,如果没有就放空框
if i + seat_transcribe >= len(gui_transcribe):
gui_data[i].grid(row=i + 1, sticky="nsew")
else:
gui_transcribe[i + seat_transcribe].grid(row=i + 1, sticky="nsew")
i += 1
# 普通模式下功能栏
def Common_Function(function_bar):
function_b = [tk.Button(function_bar, text="鼠标功能", command=Common_Mouse),
tk.Button(function_bar, text="键盘功能", command=Common_Fingerboard),
tk.Button(function_bar, text="录制功能", command=Common_Transcribe)] # 普通模式功能栏的按钮组
for i in range(len(function_b)):
function_b[i].grid(row=i, padx=5, pady=2)
# 普通模式下的初始数据栏(之后可能把前半部分整合进初始化)
def Common_Data(data_bar):
global gui_data, up_button, down_button
data_bar.rowconfigure(1, weight=1) # row为0,缩放比为1
data_bar.rowconfigure(2, weight=1) # row为1,缩放比为1
data_bar.rowconfigure(3, weight=1) # row为2,缩放比为1
data_bar.columnconfigure(0, weight=1) # column为0,缩放比为1
gui_data = [tk.LabelFrame(data_bar, text="", ),
tk.LabelFrame(data_bar, text="", ),
tk.LabelFrame(data_bar, text="", )]
for i in range(len(gui_data)):
gui_data[i].grid(row=i + 1, sticky="nsew")
# 添加两个按钮,控制gui滚动
up_button = tk.Button(data_bar, text="︿", command=Gui_UP, width=20)
up_button.grid(row=0, )
down_button = tk.Button(data_bar, text="﹀", command=Gui_DOWN, width=20)
down_button.grid(row=4, )
# gui_data[0]['text'] = '0'
# 初始化函数,初始化鼠标/键盘的GUI
def Initialization():
global gui_mouse, gui_fingerboard, gui_transcribe, data_bar
# 给每个功能添加新建GUI的栏目
gui_mouse = [tk.LabelFrame(data_bar, text="鼠标数据添加", )]
mb0 = tk.Button(gui_mouse[0], text="添加鼠标功能", command=Add_Mouse)
mb0.pack()
gui_fingerboard = [tk.LabelFrame(data_bar, text="键盘数据添加", )]
fb0 = tk.Button(gui_fingerboard[0], text="添加键盘功能", command=Add_Fingerboard)
fb0.pack()
gui_transcribe = [tk.LabelFrame(data_bar, text="录制数据添加", )]
tb0 = tk.Button(gui_transcribe[0], text="添加录制功能", command=Add_Transcribe)
tb0.pack()
works = None # 当前功能
gui_mouse = [] # 鼠标功能界面
gui_fingerboard = [] # 键盘功能界面
gui_transcribe = [] # 录制功能界面
seat_mouse = 0 # 鼠标界面位置
seat_fingerboard = 0 # 键盘界面位置
seat_transcribe = 0 # 录制界面位置
main_window = tk.Tk() # 调用Tk()创建主窗口
main_window.title("鼠标键盘模拟器") # 给主窗口起一个名字
main_window.geometry("700x800+200+100") # 大小
main_window.config(menu=Generate_Menu(main_window)) # 生成菜单栏,窗口与菜单关联
main_window.rowconfigure(0, weight=1) # row为0,缩放比为1
main_window.columnconfigure(0, minsize=65) # column为0,最小65
main_window.columnconfigure(1, weight=5) # column为1,缩放比为1
function_bar = tk.LabelFrame(main_window, text="功能栏", bg='gainsboro') # 放左边功能栏的框架
function_bar.grid(row=0, column=0, sticky="nsew")
Common_Function(function_bar) # 普通模式下功能栏
data_bar = tk.LabelFrame(main_window, text="数据栏", ) # 右边的数据栏框架
data_bar.grid(row=0, column=1, sticky="nsew")
Common_Data(data_bar) # 普通模式下数据栏
Initialization() # GUI数据初始化
# 避免玩脱的关闭线程 导出为exe时有用,在编译器还是用Ctrl+F2,这里默认的是ctrl+shift+大写键+回车
close_program = [keyboard.Key.ctrl_l,
keyboard.Key.shift,
keyboard.Key.caps_lock,
keyboard.Key.enter]
# 终止所有功能的按键,这里默认的是ctrl+shift+大写键+tab
stop_all_key = [keyboard.Key.ctrl_l,
keyboard.Key.shift,
keyboard.Key.caps_lock,
keyboard.Key.tab]
stop_listener = None
Close_Program() # 监听紧急关闭和紧急中止
main_window.mainloop() # 开启主循环,让窗口处于显示状态