tkinter 小工具监听json
import json
import time
import threading
import tkinter as tk
import tkinter.font as tf
import tkinter.messagebox
from tkinter.colorchooser import askcolor
from tkinter.filedialog import *
from tkinter.simpledialog import *
sticker_name_dict = {"filterParts": ("滤镜", (10000, 10999)),
"faceMattingPart": ("抠脸", (7000, 7999)),
"faceExchange": ("换脸", (7000, 7999)),
"parts": ("2D 贴纸", (5500, 5999)),
"fg": ("前景", (8000, 8999)),
"bg": ("背景跟踪人脸", (0, 499)),
"parts3d": ("3D 贴纸", (5500, 5999)),
"backgroundEdge": ("背景描边", (5000, 5499)),
"headAnimationParts": ("大头", (4000, 4999)),
"faceStretchParts": ("人脸拖拽", (3000, 3999)),
"faceMorph": ("美妆", (2000, 2999)),
"tryOn": ("试装", (2000, 2999)),
"beautifyParts": ("美颜", (1000, 1999)),
"3dMicroPlastic": ("3D 微整形", (500, 999)),
"segmentParts": ("分割", (0, 499))}
class Application(tk.Frame):
"""
一个经典的GUI程序
"""
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.screenwidth = self.winfo_screenwidth()
self.screenheight = self.winfo_screenheight()
self.window_width = 0.8 * self.screenwidth
self.window_height = 0.8 * self.screenheight
self.creatWidget()
self.res_buffer = []
self.json_data = None
self.txt_data = None
self.filename_json = None
self.filename_txt = None
def creatWidget(self):
"""
创建组件
:return:
"""
menubar = tk.Menu(root)
menuFile = tk.Menu(menubar, tearoff=0)
menuEdit = tk.Menu(menubar, tearoff=0)
menuHelp = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label='文件(F)', menu=menuFile)
menubar.add_cascade(label='编辑(E)', menu=menuEdit)
menubar.add_cascade(label='帮助(H)', menu=menuHelp)
menuFile.add_command(label='New', accelerator="ctrl+n")
menuFile.add_command(label='Open', accelerator="ctrl+o")
menuFile.add_command(label='Save', accelerator="ctrl+s")
menuFile.add_separator()
menuFile.add_command(label='Exit', accelerator="ctrl+q", command=root.quit)
menuEdit.add_command(label='Cut')
menuEdit.add_command(label='Copy')
menuEdit.add_command(label='Paste')
submenu = tk.Menu(menuFile)
menuFile.add_cascade(label='Import', menu=submenu, underline=0)
submenu.add_command(label="Submenu1")
root["menu"] = menubar
self.contextMenu = Menu(root)
self.contextMenu.add_command(label="背景颜色", command=self.openAskcolor)
root.bind("<Button-3>", self.creatContextMenu)
frm_1 = tk.Frame(self.master, width=self.window_width, height=0.1 * self.window_height)
frm_2 = tk.Frame(self.master, width=self.window_width / 2, height=0.95 * self.window_height)
frm_3 = tk.Frame(self.master, width=self.window_width / 2, height=0.95 * self.window_height)
frm_1.grid(row=0, column=0, columnspan=2)
frm_2.grid(row=1, column=0,sticky='nsew')
frm_2.grid_propagate(False)
frm_3.grid(row=1, column=1,sticky='nsew')
frm_3.grid_propagate(False)
self.on_test = False
self.test_var = tk.StringVar(value="开始测试")
btn_load_json = tk.Button(frm_1, text="加载json文件", bg='Pink', fg='black', font=('Arial', 12), width=15,
heigh=2, command=self.load_json)
btn_load_json.grid(row=0, column=0)
btn_load_txt = tk.Button(frm_1, text="加载图层检测文件", bg='Pink', fg='black', font=('Arial', 12), width=15,
heigh=2, command=self.load_txt)
btn_load_txt.grid(row=0, column=1)
btn_start_test = tk.Button(frm_1, textvariable=self.test_var, bg='green', fg='black', font=('Arial', 12),
width=15,
heigh=2, command=self.start_check)
btn_start_test.grid(row=0, column=2)
self.master.protocol('WM_DELETE_WINDOW', self.closeWindow)
ft = tf.Font(family='微软雅黑', size=10)
color_json = "#FF8080"
color_txt = "#FAFAD2"
self.textPad_json = tk.Text(frm_2, font=ft, height=0.9 * self.window_height, bg=color_json)
self.textPad_json.tag_config("tag_error", background="yellow", foreground="red")
self.textPad_json.insert('insert', "请点击\"加载json文件\",在\"Documents\STESData\DefaultSense\material\DefaultSense\"路径下"
"加载DefaultSense.json后,点击\"开始测试\"")
self.textPad_json.grid(row=0, column=0, sticky="nsew")
self.textPad_txt = tk.Text(frm_3, font=ft, height=0.9 * self.window_height, bg=color_txt)
self.textPad_txt.tag_config("tag_error", background="yellow", foreground="red")
self.textPad_txt.insert('insert', "请点击\"加载图层检测文件\",在\"Documents\STESData\"路径下"
"加载zpos.txt后,点击\"开始测试\"")
self.textPad_txt.grid(row=0, column=0, sticky="nsew")
self.center_window()
def center_window(self):
size = '%dx%d+%d+%d' % (self.window_width, self.window_height,
(self.screenwidth - self.window_width) / 2, (self.screenheight - self.window_height) / 2)
self.master.geometry(size)
self.master.update()
def start_check(self):
if self.test_var.get() == "开始测试":
self.textPad_json.delete(1.0, 'end')
self.textPad_txt.delete(1.0, 'end')
self.test_var.set("结束测试")
self.on_test = True
else:
self.tear_down_check()
thread_check_txt = threading.Thread(target=self.check_zpos_txt)
thread_check_txt.start()
thread_check_json = threading.Thread(target=self.check_zpos_json)
thread_check_json.start()
def getZpos_fmt1(self, part_key, sub_key=''):
if part_key in self.json_data:
if sub_key:
print(
"%s -> zPosition: %s" % (
sticker_name_dict[part_key][0], self.json_data[part_key][sub_key]["zPosition"]))
return part_key, sticker_name_dict[part_key][0], self.json_data[part_key][sub_key]["zPosition"]
else:
print("%s -> zPosition: %s" % (sticker_name_dict[part_key][0], self.json_data[part_key]["zPosition"]))
return [(part_key, sticker_name_dict[part_key][0], part_key, self.json_data[part_key]["zPosition"])]
def getZpos_fmt2(self, part_key):
result_list = []
if part_key in self.json_data:
for model_key in self.json_data[part_key].keys():
result_list.append(
(part_key, sticker_name_dict[part_key][0], model_key,
self.json_data[part_key][model_key]["zPosition"]))
print("%s %s -> zPosition: %s" %
(sticker_name_dict[part_key][0], model_key, self.json_data[part_key][model_key]["zPosition"]))
return result_list
def getZpos_fmt3(self, part_key, key_sub):
result_list = []
if part_key in self.json_data:
for model_key in self.json_data[part_key][key_sub]:
result_list.append(
(part_key, sticker_name_dict[part_key][0], model_key["name"], model_key["zPosition"]))
print(
"%s %s -> zPosition:%s " % (
sticker_name_dict[part_key][0], model_key["name"], model_key["zPosition"]))
if not self.json_data[part_key][key_sub]:
for model_key in self.json_data[part_key]["particleList"]:
result_list.append(
(part_key, sticker_name_dict[part_key][0], model_key["name"], model_key["zPosition"]))
print(
"%s %s -> zPosition:%s " % (
sticker_name_dict[part_key][0], model_key["name"], model_key["zPosition"]))
return result_list
def load_json(self):
response = tk.messagebox.askyesnocancel(title="Hi", message="是否打开了Effects Studio 并加载了素材?")
if response:
self.textPad_json.delete(1.0, 'end')
self.filename_json = askopenfile(title="打开Json文件", initialfile="DefaultSense.json", filetypes=[("配置文档", "*.json")],
defaultextension=".json")
self.textPad_json.insert('insert', "请点击\"开始测试\"\n")
if self.filename_json:
self.filename_json = self.filename_json.name
else:
self.textPad_json.insert('insert', "请在\"Documents\STESData\DefaultSense\material\DefaultSense\"路径下"
"加载DefaultSense.json后,开始测试")
else:
self.textPad_json.insert('insert', "请打开Effects Studio 加载一个贴纸素材, 再点击\"加载json文件\"按钮\n")
def load_txt(self):
response = tk.messagebox.askyesnocancel(title="Hi", message="是否打开了Effects Studio 并加载了素材?")
if response:
self.textPad_txt.delete(1.0, 'end')
self.filename_txt = askopenfile(title="打开txt文件", initialfile="DefaultSense.json", filetypes=[("图层文档", "*.txt")],
defaultextension=".txt")
self.textPad_txt.insert('insert', "请点击\"开始测试\"\n")
if self.filename_txt:
self.filename_txt = self.filename_txt.name
else:
self.textPad_txt.insert('insert', "请在\"Documents\STESData\"路径下""加载zpos.txt后,开始测试")
else:
self.textPad_txt.insert('insert', "请打开Effects Studio 加载一个贴纸素材, 再点击\"加载图层检测文件\"按钮\n")
def creatContextMenu(self, event):
self.contextMenu.post(event.x_root, event.y_root)
def openAskcolor(self):
s1 = askcolor(color='red', title="选择背景色")
self.textPad_json.config(bg=s1[1])
def tear_down_check(self):
self.on_test = False
self.test_var.set("开始测试")
self.textPad_json.delete(1.0, "end")
self.textPad_txt.delete(1.0, "end")
self.res_buffer.clear()
self.txt_data = None
self.json_data = None
def display_check_result(self, z_pos_info):
info = z_pos_info[1] + " " + z_pos_info[2] + "-> zPosition: " + str(z_pos_info[3])
start, end = int(sticker_name_dict[z_pos_info[0]][1][0]), int(sticker_name_dict[z_pos_info[0]][1][1])
if int(z_pos_info[3]) < start or int(z_pos_info[3]) > end:
self.textPad_json.insert('insert', info + " changed. Please check!\n", ("tag_error"))
else:
self.textPad_json.insert('insert', info + "\n")
def get_json_data(self):
try:
with open(self.filename_json, 'r', encoding='utf-8') as f:
json_data = json.load(f)
return json_data
except FileNotFoundError:
self.textPad_json.delete(1.0, "end")
self.textPad_json.insert('insert',
"请点击\"加载json文件\",在\"Documents\STESData\DefaultSense\material\DefaultSense\"路径下"
"加载DefaultSense.json后,开始测试\n")
self.json_data = None
def get_txt_data(self):
try:
with open(self.filename_txt, 'r', encoding='utf-8') as f:
txt_data = f.read()
return txt_data
except FileNotFoundError:
self.textPad_txt.delete(1.0, "end")
self.textPad_txt.insert('insert', "请点击\"加载图层检测文件\",在\"Documents\STESData\"路径下"
"加载zpos.txt后,点击\"开始测试\"")
self.txt_data = None
def check_zpos_txt(self):
if not self.filename_txt:
self.textPad_txt.delete(1.0, "end")
self.textPad_txt.insert('insert', "请点击\"加载图层检测文件\",在\"Documents\STESData\"路径下"
"加载zpos.txt后,点击\"开始测试\"")
return
while self.on_test:
data_buffer = self.get_txt_data()
if data_buffer == self.txt_data:
continue
else:
self.txt_data = data_buffer
layer_info_all = re.findall('posLayer\s*(\w+)\s*zpos\s*(-*\d+)\s*[module_]*type\s*(\d+)', self.txt_data)
layer_zpos = [(info[0], info[1]) for info in layer_info_all]
iner_info_all = re.findall('posIner\s*(\w+)\s*zpos\s*(-*\d+)\s*groupid\s*(\S+)\s*[module_]*type\s*(\d+)\s*file\s(.*)',
self.txt_data)
iner_zpos = [(info[0], info[1]) for info in iner_info_all]
self.textPad_txt.delete(1.0, "end")
if len(layer_zpos) != len(iner_zpos):
self.textPad_txt.insert('insert', "内部图层与Studio显示图层数量不一致!\n", ("tag_error"))
print("内部图层与Studio显示图层数量不一致!\n")
dif_all = set(layer_zpos) ^ set(iner_zpos)
for dif in dif_all:
if dif in layer_zpos:
self.textPad_txt.insert('insert', str(dif) + " 在显示图层\n", ("tag_error"))
else:
self.textPad_txt.insert('insert', str(dif) + " 在Studio内部图层图层\n", ("tag_error"))
else:
i = 0
for layer_zpos_i, iner_zpos_j in zip(layer_zpos, iner_zpos):
display_zpos = True
if int(iner_zpos_j[1]) < 0:
self.textPad_txt.insert('insert', "zpos < 0 posIner -> 索引 %d :name: %s, zpos:%s, groupId:%s, type:%s\n"
% (i, iner_info_all[i][0],iner_info_all[i][1], iner_info_all[i][2], iner_info_all[i][3]), ("tag_error"))
if i < len(iner_zpos) - 1 and int(iner_zpos[i][1]) < int(iner_zpos[i + 1][1]):
display_zpos = False
self.textPad_txt.insert('insert', "inter zpos异常 -> 索引%d: %s 小于 索引%d: %s\n"
% (i, iner_zpos[i], i + 1, iner_zpos[i + 1]), ("tag_error"))
if layer_zpos_i != iner_zpos_j:
if layer_zpos_i[1] == iner_zpos_j[1]:
self.textPad_txt.insert('insert',"素材名称 -> 索引%d: layer_zpos: %s 不等于 iner_zpos: %s \n"
% (i, layer_zpos_i, iner_zpos_j), ("tag_error"))
elif layer_zpos_i[0] == iner_zpos_j[0] and display_zpos:
self.textPad_txt.insert('insert',
"posIner -> 索引 %d :name: %s, zpos:%s, groupId:%s, type:%s\n" %
(i, iner_info_all[i][0], iner_info_all[i][1], iner_info_all[i][2],
iner_info_all[i][3]))
else:
self.textPad_txt.insert("insert", "顺序错位 -> 索引%d: layer_zpos: %s 不等于 iner_zpos: %s\n"
% (i, layer_zpos_i, iner_zpos_j), ("tag_error"))
else:
if display_zpos:
self.textPad_txt.insert('insert', "posIner -> 索引 %d :name: %s, zpos:%s, groupId:%s, type:%s\n" %
(i, iner_info_all[i][0],iner_info_all[i][1], iner_info_all[i][2], iner_info_all[i][3]))
i += 1
time.sleep(3)
def check_zpos_json(self):
if not self.filename_json:
self.textPad_json.delete(1.0, "end")
self.textPad_json.insert('insert',
"请点击\"加载json文件\",在\"Documents\STESData\DefaultSense\material\DefaultSense\"路径下"
"加载DefaultSense.json后,开始测试\n")
return
while self.on_test:
res_buffer_current = []
json_data_buffer = self.get_json_data()
if not json_data_buffer:
break
if json_data_buffer == self.json_data:
continue
else:
self.json_data = json_data_buffer
res = self.getZpos_fmt2("filterParts")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt2("faceMattingPart")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt1("faceExchange")
if res:
res_buffer_current = res_buffer_current + res
if "parts" in self.json_data:
for key in self.json_data["parts"]:
z_pos = self.json_data["parts"][key]["zPosition"]
if "fg" in key:
res_buffer_current.append(("fg", "前景", key, z_pos))
print("前景 %s -> zPosition:%s " % (key, z_pos))
elif "hand" in key:
res_buffer_current.append(("parts", "手部", key, z_pos))
print("手部 %s -> zPosition:%s " % (key, z_pos))
elif "cat" in key:
res_buffer_current.append(("parts", "猫脸", key, z_pos))
print("猫脸 %s -> zPosition:%s " % (key, z_pos))
elif "dog" in key:
res_buffer_current.append(("parts", "狗脸", key, z_pos))
print("狗脸 %s -> zPosition:%s " % (key, z_pos))
elif "bg" in key:
res_buffer_current.append(("bg", "背景跟踪人脸", key, z_pos))
print("背景跟踪人脸 %s -> zPosition:%s " % (key, z_pos))
else:
res_buffer_current.append(("parts", "2D贴纸", key, z_pos))
print("2D贴纸 %s -> zPosition:%s " % (key, z_pos))
res = self.getZpos_fmt3("parts3d", "modelList")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt1("backgroundEdge")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt2("headAnimationParts")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt2("faceStretchParts")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt3("faceMorph", "makeups")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt3("tryOn", "types")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt2("beautifyParts")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt1("3dMicroPlastic", "defaultParts")
if res:
res_buffer_current = res_buffer_current + res
res = self.getZpos_fmt2("segmentParts")
if res:
res_buffer_current = res_buffer_current + res
self.textPad_json.delete(1.0, "end")
dif = list(set(res_buffer_current) ^ set(self.res_buffer))
for ele in dif:
if ele in self.res_buffer:
self.res_buffer.remove(ele)
else:
self.res_buffer.append(ele)
for info in self.res_buffer:
self.display_check_result(info)
time.sleep(0.5)
def closeWindow(self):
response = tk.messagebox.askyesnocancel(title="退出", message="您确定要退出吗?")
if response:
root.destroy()
self.on_test = False
root = tk.Tk()
root.title("Studio zpos Tools")
root.resizable(False, False)
app = Application(master=root)
root.mainloop()
![在这里插入图片描述](https://img-blog.csdnimg.cn/d3e6e881a1dc40528ce8ed6f0363e836.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rKn5rW35LqM6Ziz,size_20,color_FFFFFF,t_70,g_se,x_16)