tkinter 小工具监听json

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.grid()
        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
        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')

        # 为File继续添加子菜单
        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)

        # 添加label标签
        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)  # 设置label
        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)  # 设置label

        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)  # 设置label
        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"  # Pink
        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
            # self.txt_data = None
            # self.json_data  = None

        else:
            self.tear_down_check()

        # 开启线程实时获取Effects Studio zpos.txt数据
        thread_check_txt = threading.Thread(target=self.check_zpos_txt)
        thread_check_txt.start()

        # 开启线程实时获取Effects Studio json数据
        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"))
                        # print(str(dif), "在内部图层\n")
                    else:
                        self.textPad_txt.insert('insert', str(dif) + " 在Studio内部图层图层\n", ("tag_error"))
                        # print(str(dif), "在Studio显示图层图层\n")
            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"))
                            # print("素材名称 -> 索引%d: layer_zpos: %s 不等于  iner_zpos %s " % (i, layer_zpos_i, iner_zpos_j))
                        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]))
                            # self.textPad_txt.insert('insert', "zpos不一致 -> 索引%d: layer_zpos: %s 不等于  iner_zpos: %s\n"
                            #                         % (i, layer_zpos_i, iner_zpos_j), ("tag_error"))
                            # print("zpos不一致 -> 索引%d: layer_zpos: %s 不等于  iner_zpos %s " % (
                            # i, layer_zpos_i, iner_zpos_j))
                        else:
                            self.textPad_txt.insert("insert", "顺序错位 -> 索引%d: layer_zpos: %s 不等于  iner_zpos: %s\n"
                                                    % (i, layer_zpos_i, iner_zpos_j), ("tag_error"))
                            # print("顺序错位 -> 索引%d: layer_zpos: %s 不等于  iner_zpos %s " % (i, layer_zpos_i, iner_zpos_j))
                    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

            # 2D 贴纸
            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))

            # 3D 贴纸
            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

            # 3D 微整形
            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

            # 更新buffer
            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()


在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值