python Tkinter

功能:

       1 界面上展示圖片,log,  pass、fail、total、rate

       2 自動開始運行 Main_process内部的 代碼,如果pass,播放过站语音,等待一秒,循环执行main_process,如果fail,播放不能通过的语音,测试暂停,展示图片,当按下空格键时开始下一轮循环。

      3 界面中图片区域可以双击放大,查看图片细节

      4 device可以点击修改,当修改窗口打开时,不可再次点击该按钮,防止多开。

        注意:

           可直接替換Main_process中的下面一段:

# main_process(loger).camera_run()
status, result = self.getsfis()
loger.info(f"{result}")

        具體界面效果如下:

完整代碼如下:

import os
import queue
import winsound
from pathlib import Path
# from scancamera import main_process
import pysfis
from tkinter.font import Font
from ttkbootstrap import *
import tkinter as tk
from tkinter import scrolledtext,END
from tkinter import messagebox
import time
import logging
from  PIL import Image,ImageTk
import threading
import chardet


def readDATfile(path):
    tt = "NA"
    with open(path, "rb")as f:
        fixid = f.read()
        f_charInfo = chardet.detect(fixid)
        tt = fixid.decode(f_charInfo['encoding'])
        return tt

def window_reflesh():
    return window.after(100,window_reflesh)

#    重寫logging模塊中的emit,將log寫入控件中。
class TextHandler(logging.Handler):
    def __init__(self, logtext):
        logging.Handler.__init__(self)
        self.log = logtext
    @staticmethod
    def current_time():
        current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        return current_time
    def emit(self, record):
        msg = self.format(record)

        logstr = str(TextHandler.current_time()) + " " + str(msg) + "\n"
        self.log.insert('end',logstr)
        self.log.see(END)

class Armani(threading.Thread):
    def __init__(self):
        super().__init__()
        self.testpath = "D:\LabelAOI\Test"
        #       暂停标志, 如果Fail,界面停止, 如果pass,暂停1s重新检测
        self.pause_flag = False
        #       暂停 触发标致,防止多次触发, 多次测试
        self.test_running = False
        #       device 修改标志,    防止多次触发修改弹窗
        self.device_running = False
        #       测试结果标致
        self.resutl = "Pass"

    def changedevice(self):
        if self.device_running:
            return
        self.device_running = True
        device.config(state=tk.DISABLED)  # 禁用按钮
        def checkstr():
            new_device = devicevar.get()
            if not new_device.isdigit():
                messagebox.showerror("ERROR","the new device is not isdigit")
            elif not len(new_device) == 6:
                messagebox.showerror("ERROR","the device lenght is eque 6")
            else:
                messagebox.showinfo("Tips","Alter the device is successful!")
                device.config(state=tk.NORMAL)  # 重新启用按钮
                self.device_running = False
                chage_dev_ui.destroy()
                device_id.set(new_device)
                with open(device_path,'w')as f:
                    f.write(new_device)
            window.after(100,window_reflesh)
        chage_dev_ui = tk.Toplevel(window)
        chage_dev_ui.geometry("300x200")
        chage_dev_ui.title("change the deviceid")
        devicevar = tk.StringVar()
        tk.Label(chage_dev_ui, text='new device:',font=("", 15)).place(x=10,y=30)
        tk.Entry(chage_dev_ui,textvariable=devicevar,width=10,font=("", 15)).place(x=120,y=30)
        tk.Button(chage_dev_ui,text="confirm",height=3,width=10,command=checkstr).place(x=110,y=70)

        def on_popup_close():
            self.device_running = False
            device.config(state=tk.NORMAL)  # 重新启用按钮
            chage_dev_ui.destroy()

        chage_dev_ui.protocol("WM_DELETE_WINDOW", on_popup_close)  # 绑定关闭事件

    def run(self):
        t1 = threading.Thread(target=self.Main_Process)
        t1.start()

    def getsfis(self):
        SSNFile = os.path.join(self.testpath, "SSN.DAT")
        if not os.path.exists(SSNFile):
            self.resutl = "Fail"
            errorinfor = "Camera not fount!"
            return False, errorinfor

        ISN = readDATfile(SSNFile).strip()
        #   获取节点信息
        status, result = pysfis.check_route(ISN)
        # if not status or "WRONG STEP" in result[1]:
        if not status:
            return status, result
        routeinfor = result[1]
        loger.info("SFIS ROUTE:{}".format(routeinfor))
        #   获取工单号
        status, result = pysfis.check_MO(ISN)
        if not status:
            return status, result
        MO = result[2]
        loger.info(f"SFIS MO:{MO}")
        time.sleep(0.5)
        #   获取机种名
        status, result = pysfis.check_model(ISN)
        if not status:
            return status, result
        model = result[2]
        time.sleep(0.5)
        loger.info(f"SFIS 机种名:{model}")
        #   获取90料号
        status, result = pysfis.check_90info(ISN)
        if not status:
            return status, result
        PN90 = result[3]
        time.sleep(0.5)
        loger.info(f"SFIS 90料号:{PN90}")
        return True, "SFIS is OK"

    def Main_Process(self):
        while True:
            if not self.test_running:
                break
            else:
                time.sleep(0.5)
        self.Result_wait()
        logtext.delete('1.0', END)
        self.test_running = True
        # main_process(loger).camera_run()
        status, result = self.getsfis()
        loger.info(f"{result}")

        self.image_open = os.path.join(self.testpath, "L_main_CAM_basler.jpg")
        self.load_image(self.image_open)
        viewimg.bind("<Double-Button-1>", lambda event: self.show_image(self.image_open))
        self.END()

    def END(self):

        if self.resutl == "Fail":
            self.Result_Fail()
            self.pause_flag = True
            self.resutl = "PASS"
            self.Main_Process()
        else:
            self.Result_pass()
            self.resutl = "Fail"
            self.test_running = False
            self.Main_Process()

    def Result_Fail(self):
        result_var.set("FAIL")
        result_font = Font(family="Arial", size=79, weight="bold")
        result.config(fg = 'red',font=result_font)
        result.place(x=540, y=400)
        winsound.PlaySound("D:\LabelAOI\source\FAIL.wav", winsound.SND_ALIAS)
        self.load_image(self.image_open)
        viewimg.bind("<Double-Button-1>", lambda event: self.show_image(self.image_open))
        window.after(500, window_reflesh)

    def on_key_press(self, event=None):
        if self.pause_flag:
            self.pause_flag = False
            window.unbind('<space>')  # 解绑按键事件
            self.test_running = False
            self.load_image(self.image_open)
            viewimg.bind("<Double-Button-1>", lambda event: self.show_image(self.image_open))
            window.after(500, window_reflesh)

    def Result_wait(self):
        result_var.set("测试中...")
        result_font = Font(family="Arial", size=45, weight="bold")
        result.config(fg = 'brown', font = result_font)
        result.place(x=540, y=430)
        window.bind('<space>', self.on_key_press)

    def Result_pass(self):
        result_var.set("PASS")
        result_font = Font(family="Aria", size=68, weight="bold")
        result.config(fg = 'green',font = result_font)
        result.place(x=530, y=400)
        winsound.PlaySound("D:\LabelAOI\source\PASS.wav", winsound.SND_ALIAS)
        window.after(500, window_reflesh)

    def show_image(self,imagepath):
        self.show_image_UI = tk.Toplevel(window)
        self.show_image_UI.geometry("700x500")
        png = Image.open(imagepath)
        filename = Path(imagepath)
        name = filename.name
        self.show_image_UI.title(name)
        canvas = tk.Canvas(self.show_image_UI, bg='white', highlightthickness=0)
        canvas.pack(side=LEFT, anchor=CENTER, fill=BOTH, expand=YES)
        self.image = ImageTk.PhotoImage(image=self.image_resize(image = png, event = None, window = self.show_image_UI, frame = canvas))
        self.image1 = canvas.create_image(self.win_size(self.show_image_UI, canvas)[0] // 2, self.win_size(self.show_image_UI, canvas)[1] // 2, image=self.image)
        self.show_image_UI.bind(sequence = '<Configure>', func = self.handler_adaptor(self.image_resize, image = png, window = self.show_image_UI, frame = canvas))

    def load_image(self, filename):
        self.image = Image.open(filename)
        self.photo = ImageTk.PhotoImage(image=self.image_resize(image=self.image, event=None, window= window,frame = viewimg))
        self.image1 = viewimg.create_image(self.win_size(window, viewimg)[0]//2, self.win_size(window, viewimg)[1] // 2, image=self.photo)
        viewimg.bind(sequence='<Configure>', func=self.handler_adaptor(self.image_resize, image=self.image, window = window, frame = viewimg))

    def image_resize(self,event=None, image=None, window=None, frame=None):
        if event is None:
            screen_width, screen_height = self.win_size(window, frame)
        else:
            screen_width, screen_height = event.width, event.height
        raw_width, raw_height = image.size[0], image.size[1]
        max_width, max_height = raw_width, screen_height
        min_width = max(raw_width, max_width)
        # 按照比例缩放
        min_height = int(raw_height * min_width / raw_width)
        # 第1次快速调整
        while min_height > screen_height:
            min_height = int(min_height * .9533)
        # 第2次精确微调
        while min_height < screen_height:
            min_height += 1
        # 按照比例缩放
        min_width = int(raw_width * min_height / raw_height)
        # 适应性调整
        while min_width > screen_width:
            min_width -= 1
        # 按照比例缩放
        min_height = int(raw_height * min_width / raw_width)
        images = image.resize((min_width, min_height), Image.Resampling.LANCZOS)
        if event is None:
            return images
        else:
            global png
            frame.delete(self.image1)
            png = ImageTk.PhotoImage(images)
            frame.create_image(screen_width // 2, screen_height // 2, image=png)

    def win_size(self, window, frame):
        """
        获取窗口大小,在没有bind事件时使用
        """
        window.update()
        width = frame.winfo_width()
        height = frame.winfo_height()
        return width, height

    def handler_adaptor(self, fun, **kwds):
        return lambda event, fun=fun, kwds=kwds: fun(event, **kwds)

if __name__ == '__main__':
    device_path = r"D:\LABELAOI\Config\DEVICE.INI"
    webip_path = r"D:\LABELAOI\Config\WEBIP.INI"
    TooVer = "Armani"
    window = tk.Tk()
    window.title(f'Armani test')
    window.geometry("800x600")
    title = tk.Label(window, text = 'show log Detials', font=("",15))
    title.place(x=10, y=10)
    viewimg = tk.Canvas(window, height =428, width = 490 , bg="green")
    viewimg.place(x=10, y=40)
    webver = tk.StringVar()
    device_label = tk.Label(window, text='device:', font=("", 15))
    web_label = tk.Label(window, text='webip:', font=("", 15))
    deviceid = readDATfile(device_path).strip()
    webip = readDATfile(webip_path).strip()
    device_id = tk.StringVar()
    device_id.set(deviceid)
    device = tk.Button(window,textvariable=device_id,font=("",10),command=Armani().changedevice)
    webserver = tk.Button(window,text=webip, width=25, height=1, anchor=tk.CENTER, font=("",10))
    device_label.place(x=530, y=80)
    device.place(x=600, y=80)
    web_label.place(x=530, y=120)
    webserver.place(x=600, y=120)
    passcout = tk.Label(window,  text = 'Pass:', font=("",15), fg='green')
    passcout.place(x=530, y=160)
    errorcout = tk.Label(window, text='Error:', font=("", 15), fg='red')
    errorcout.place(x=530, y=200)
    totalout = tk.Label(window, text='Total:', font=("", 15), fg='brown')
    totalout.place(x=680, y=160)
    rate = tk.Label(window, text='Rate:', font=("", 15), fg='brown')
    rate.place(x=680, y=200)
    result_var = tk.StringVar()
    result_var.set("测试中...")
    result_font = Font(family="Arial", size=45, weight="bold")
    result = tk.Label(window, textvariable = result_var, font=result_font, fg = 'brown', anchor=tk.CENTER)
    result.place(x = 540, y=430)
    contect_font = Font(family="Arial", size=22, weight="bold")
    contect = tk.Button(window, text='异常联系人', height=1, width=13, font=contect_font, fg = 'brown', bg="yellow", anchor=tk.CENTER)
    contect.place(x=530, y=520)

    errorTip = tk.Label(window, text = "錯誤提示", font=("", 15), fg = 'brown', anchor=tk.W)
    errorTip.place(x=530, y=240)

    error_variable = tk.StringVar()
    error_variable.set("多貼,31d0多貼請檢查!")
    result_font = Font(family="Arial", size=15, weight="bold")
    errorinfo = tk.Label(window, textvariable = error_variable, font=result_font, fg = 'brown', anchor=tk.W)
    errorinfo.place(x=530, y=270)

    logtext = scrolledtext.ScrolledText(window, width=70, height=7)
    logtext.place(x=10, y=480)
    loger = logging.getLogger("log")
    loger.setLevel(logging.INFO)
    Handler = TextHandler(logtext)
    loger.addHandler(Handler)
    Armani().run()
    window.mainloop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值