from tkinter import *
import tkinter as tk
from tkinter import ttk, filedialog, Text
from tkinter import Toplevel, Entry, messagebox
from tkinter.filedialog import askdirectory,askopenfilename
from PIL import Image, ImageTk
import cv2
#import pytesseract
import threading
import pyautogui
import os
import numpy as np
import pandas as pd
#import random
#import sched #(计划任务)
#import schedule
import winsound #电脑报警音
#import pyodbc
import pymysql
import mysql.connector
from datetime import datetime
import time
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,NavigationToolbar2Tk)
from matplotlib.font_manager import FontProperties
class MainWindow:
def __init__(self, master):
#self.master = master
#self.master.title("登录数据库")
self.master = master
self.master.title("登录数据库")
print('系统登录-总界面')
self.flag_conn = 0
label_topic_0 = tk.Label(self.master, text="电力设备热致故障温度预警系统", font=('楷体', 22))
label_topic_0.place(x=40, y=50)
#label_topic_0.attributes("-alpha", 0.5) # 设置透明度为50%
label_topic_1 = ttk.Label(self.master, text="登 录 数 据 库", font=('楷体', 22))
label_topic_1.place(x=140, y=100)
label_server=tk.Label(self.master,text = "Server",width=8, height=2,font=('宋体', 14))
label_server.place(x=50, y=200)
self.entry_item_01 = tk.Entry(self.master,width=30, bg="white",font=('宋体', 14))
self.entry_item_01.place(x=150 , y=210)
default_text1 = 'localhost'
self.entry_item_01.insert(0, default_text1)
label_database=tk.Label(self.master,text = "Database",width=8, height=2,font=('宋体', 14))
label_database.place(x=50, y=250)
self.entry_item_02 = tk.Entry(self.master,width=30, bg="white",font=('宋体', 14))
self.entry_item_02.place(x=150 , y=260)
default_text2= 'pic_temp'
self.entry_item_02.insert(0, default_text2)
label_Username=tk.Label(self.master,text = "Username",width=8, height=2,font=('宋体', 14))
label_Username.place(x=50, y=300)
self.entry_item_03 = tk.Entry(self.master,width=30, bg="white",font=('宋体', 14))
self.entry_item_03.place(x=150 , y=310)
default_text3= 'root'
self.entry_item_03.insert(0, default_text3)
label_Password=tk.Label(self.master,text = "Password",width=8, height=2,font=('宋体', 14))
label_Password.place(x=50, y=350)
self.entry_item_04 = tk.Entry(self.master,width=30, bg="white",font=('宋体', 14))
self.entry_item_04.place(x=150 , y=360)
default_text4= '******'
self.entry_item_04.insert(0, default_text4)
self.radio_win = tk.StringVar() # 创建一个StringVar变量,用于存储选中的值
self.radio_win.set('1')
#radio_var.set(None)
# 创建第一个单选框
#radio_button1 = tk.Radiobutton(self.master, text="Windows认证",variable=self.radio_win, value="1",font=('宋体', 14))
#radio_button1.place(x=150, y=400)
# 创建第二个单选框
#radio_button2 = tk.Radiobutton(self.master, text="Sql认证",variable=self.radio_win, value="2",font=('宋体', 14))
#radio_button2.place(x=300, y=400)
label_status=tk.Label(self.master,text = "连接状态",width=8, height=2,font=('宋体', 14))
label_status.place(x=50, y=450)
self.label_conn=tk.Label(self.master,text = "------",width=15, height=2,font=('宋体', 14))
self.label_conn.place(x=150, y=450)
self.button_login_sql = tk.Button(self.master, text="连接", command=self.login_sql,width=10, height=2,font=('宋体', 14))
self.button_login_sql.place(x=50, y=550)
self.button_login = tk.Button(self.master, text="登录", command=self.open_window_main,width=10, height=2,font=('宋体', 14))
self.button_login.place(x=200, y=550)
self.button_close = tk.Button(self.master, text="退出", command=self.close,width=10, height=2,font=('宋体', 14))
self.button_close.place(x=350, y=550)
def login_sql(self):
# 数据库连接字符串
server = self.entry_item_01.get()
database = self.entry_item_02.get()
username1 = self.entry_item_03.get()
password1 = self.entry_item_04.get()
# 尝试连接数据库
try:
conn=pymysql.connect(host=server,
user=username1,
password=password1,
port=3306,
db=database)
print("数据库连接成功!")
self.label_conn.configure(bg='lightgreen',fg='blue',text='数据库连接成功')
self.flag_conn = 1
except Exception as e:
print("Excel连接成功:", e)
self.flag_conn = 1
self.label_conn.configure(bg='lightgreen',fg='blue',text='Excel连接成功')
finally:
if conn: # 确保在操作完成后关闭连接:
conn.close() # 关闭连接
def open_window_main(self):
if self.flag_conn == 1:
self.master.iconify() # 最小化窗口
# 创建新窗口的实例
self.new_window_main = tk.Toplevel(self.master)
# 传递新窗口作为参数给另一个窗口类
self.app_main = NewWindow_main(self.new_window_main)
self.flag_conn = 0
else:
print('连接错误')
messagebox.showinfo("提示", "连接错误,请重新连接")
def close(self):
print('关闭窗口')
#self.btn_open_window_sql.config(state=tk.NORMAL)
#self.btn_open_window_video.config(state=tk.NORMAL)
self.master.destroy()
#root.deiconify() # 显示主窗口
class NewWindow_main:
def __init__(self, master):
self.window_main = master
# setting the title
self.window_main.title('电力设备热致故障温度预警系统')
self.window_main.geometry("1300x700+150+150")
print('系统登录-主界面')
label_topic_0 = ttk.Label(self.window_main, text="电力设备热致故障温度预警系统", font=('楷体', 36)).place(x=310, y=200)
#label_topic_1 = ttk.Label(self.window_main, text="一、图片数据采集", font=('楷体', 26)).place(x=410, y=400)
label_topic_2 = ttk.Label(self.window_main, text=" 图片数据采集", font=('楷体', 26)).place(x=410, y=500)
#self.btn_open_window_sql = tk.Button(self.window_main, text="进入",font=('宋体', 16), command=self.open_window_sql,width=10, height=2)
#self.btn_open_window_sql.place(x=820, y=390)
#self.btn_open_window_sql.config(state=tk.DISABLED)
self.btn_open_window_video = tk.Button(self.window_main, text="进入", font=('宋体', 16) ,command=self.open_window_video,width=10, height=2)
self.btn_open_window_video.place(x=820, y=490)
#self.btn_open_window_video.config(state=tk.DISABLED)
self.window_main.mainloop()
def open_window_sql(self):
# 创建新窗口的实例
self.new_window_sql = tk.Toplevel(self.window_main)
# 传递新窗口作为参数给另一个窗口类
self.app_sql = NewWindow_sql(self.new_window_sql)
def open_window_video(self):
# 创建新窗口的实例
self.new_window_video = tk.Toplevel(self.window_main)
# 传递新窗口作为参数给另一个窗口类
self.app_video = NewWindow_video(self.new_window_video)
#self.window_main.mainloop()
class NewWindow_video:
def __init__(self, master):
#self.master_video = master
#self.master_video.title("主窗口")
window_video = master
# 在新窗口中添加一些组件
#tk.Label(self.master_video, text="这是一个新窗口_video").pack()
window_video.title('电力设备热致故障温度预警系统')
self.window_video = window_video
print('系统登录-视频图像')
global frame1,point_count
global output,fig
output = None
fig = None
frame1 = None
point_count = 0
# dimensions of the main window
window_video.geometry("1300x700+150+150")
label_topic_1 = Label(window_video, text="实时温度检测与预警", font=('楷体', 26)).place(x=450, y=30)
def open_camera():
print('进入_摄像头开启')
global cap,video_path
global flag_picture,flag_video
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW) # 激活摄像头
flag_video = 1
flag_picture = 0
if not cap.isOpened():
print("无法打开摄像头")
return
play_display()
def close_camera():
print('进入_摄像头关闭')
global cap,video_path
if cap:
cap.release() # 释放摄像头
#cap = None
canvas1.delete("all") # 清空Canvas上的所有内容
time.sleep(1)
cv2.destroyAllWindows() # 销毁窗口
if cap:
cap.release() # 释放摄像头
#cap = None
canvas1.delete("all") # 清空Canvas上的所有内容
time.sleep(1)
cv2.destroyAllWindows() # 销毁窗口
def record_camera():
print('进入_保存视频')
global cap,video_path
#flag_save_camera = 1
def record_camera1():
fourcc = cv2.VideoWriter_fourcc(*'XVID')
fps = 20.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 获取当前时间
now = datetime.now()
# 格式化时间
current_datetime = now.strftime("%Y%m%d_%H%M%S")
print("当前日期和时间:", current_datetime)
#file_name = 'pic_temp'+str(current_datetime)+'.avi'
file_name = 'pic_temp_'+str(current_datetime)+'.mp4'
out = cv2.VideoWriter(file_name, fourcc, fps, (width, height))
#out = cv2.VideoWriter('pic_temp.avi', fourcc, fps,(620,300))
# 捕获视频帧并保存
while cap.isOpened():
ret, frame = cap.read()
if not ret:
print("无法读取视频帧")
break
out.write(frame)
cv2.imshow('Record_video', frame)
if cv2.waitKey(10) & 0xFF == ord('q'):
# 释放资源
#cap.release()
#out.release()
#cv2.destroyAllWindows()
break
#th_record_camera1 = threading.Thread(target=record_camera1,args=sstime)
th_record_camera1 = threading.Thread(target=record_camera1)
th_record_camera1.start()
#threading.Thread(target=save_camera1).start()
def select_file():
print('进入_选择文件')
global cap,video_path
global flag_picture,flag_video
path_ = askopenfilename()
path.set(path_)
video_path = path_
print('video_path:',video_path)
suffix = os.path.splitext(video_path)[1]
#_, ext = os.path.splitext(video_path)
#print('ext:',_, ext)
## 读取图像,解决imread不能读取中文路径的问题
def cv_imread(filePath):
cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)
## imdecode读取的是rgb,如果后续需要opencv处理的话,需要转换成bgr,转换后图片颜色会变化
##cv_img=cv2.cvtColor(cv_img,cv2.COLOR_RGB2BGR)
return cv_img
if suffix in ['.jpg', '.png', '.jpeg']: # 根据需要添加其他图片格式
#cap = cv2.imread('87.jpg')
cap = cv_imread(video_path)
if cap is None:
print("图像文件未找到或路径错误")
flag_picture = 1
flag_video = 0
#cv2.imshow('Image', cap)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
else:
flag_video = 1
flag_picture = 0
cap = cv2.VideoCapture(video_path)
#cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
# 显示画面
def play_display():
print('进入_显示画面')
global flag_picture,flag_video,cap
if flag_picture == 1 and flag_video == 0:
play_pic()
if flag_picture == 0 and flag_video==1:
play_video1()
def play_pic():
global cap
#cap = cv2.imread(video_path)
selected_option = radio_var.get()
if selected_option == '3':
# 定义矩形的左上角和右下角坐标
x11=entry_x41.get()
y11=entry_y41.get()
#x=int(x11)-130 # 存在偏差,进行校正
#y=int(y11)-260
x=int(x11) # 存在偏差,进行校正
y=int(y11)
print('x_y:',x,'_',y)
w=50
h=50
#x, y, w, h = 280, 240, 70,70 # 例如,从(100, 100)到(300, 300)
# 在图片上绘制矩形框
#print('1111')
cv2.rectangle(cap, (x, y), (x+w, y+h), (0, 255, 0), 2) # 颜色为绿色,线宽为2
# 将OpenCV的图像数据转换为PIL图像格式,因为Tkinter需要PIL图像
#img_pil = Image.fromarray(cap)
# 使用Pillow将PIL图像转换为Tkinter兼容的PhotoImage格式
#img_tk = ImageTk.PhotoImage(img_pil)
#img_tk = Image.fromarray(img_tk)
#img_tk = img_tk.resize((width, height),Image.LANCZOS) # 调整视频帧大小以适应Canvas大小
#canvas1.create_image(0, 0, anchor=tk.NW, image=cap)
# 保持对图像的引用,防止被垃圾回收
#canvas1.image = img_tk
# 将视频帧显示在Canvas上
img = cv2.cvtColor(cap, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
img = img.resize((width, height),Image.LANCZOS) # 调整视频帧大小以适应Canvas大小
# 将PIL图像转换为ImageTk图像
img = ImageTk.PhotoImage(image=img)
canvas1.create_image(0, 0, anchor=tk.NW, image=img)
canvas1.img = img
# 显示图片
#cv2.imshow('Image with Rectangle', cap)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
# 如果需要保存图片
#cv2.imwrite('image_with_rectangle.jpg', cap)
def play_video1():
global cap,frame1,video_path
#global stop_event,thread_video
#cap = cv2.VideoCapture(video_path)
def play():
#print('cap:',cap)
ret, frame = cap.read()
#print('ret1:',ret)
#print('frame:',frame)
if ret:
# 确定矩形的位置和大小
#print('ret2:',ret)
selected_option = radio_var.get()
if selected_option == '3':
#x = 800
#y = 300
x11=entry_x41.get()
y11=entry_y41.get()
x=int(x11) # 存在偏差,进行校正
y=int(y11)
w =50
h = 50
#print('1111+++')
try:
cv2.rectangle(frame,(x, y), (x+w, y+h), (0,255, 0), thickness=6) # 使用FILLED来填充矩形 绿色
except OSError as err:
print("OS error: {0}".format(err))
#print('2222')
frame1=frame
#out.write(frame)
# 将视频帧显示在Canvas上
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(img)
img = img.resize((width, height),Image.LANCZOS) # 调整视频帧大小以适应Canvas大小
# 将PIL图像转换为ImageTk图像
img = ImageTk.PhotoImage(image=img)
canvas1.create_image(0, 0, anchor=tk.NW, image=img)
canvas1.img = img
canvas1.after(10, play_video1)
#threading.Thread(target=play).start()
#stop_event = threading.Event()
#thread_video = threading.Thread(target=play,args=(stop_event,))
thread_video = threading.Thread(target=play, daemon=True) #daemon=True 守护线程
thread_video.start()
"""
while thread.is_alive():
print("Thread is still running")
time.sleep(1)
print("Thread has finished")
"""
def stop_play():
print('进入_停止播放')
global cap
#global stop_event,thread_video
#stop_event.set()
#thread_video.join()
cap.release()
cv2.destroyAllWindows()
"""
def delayed_action():
time.sleep(3) # 延时5秒
get_rgb_point(event)
print("延时结束")
"""
"""
def on_canvas1_click(event):
global cap,frame1
print('frame1:',frame1)
if frame1 is not None:
x, y = int(event.x), int(event.y) # 获取点击坐标(注意转换坐标系)
pixel = frame1[y, x] # 获取RGB值,注意opencv的BGR顺序,此处已转换为RGB显示,所以直接取用即可
print(f"Clicked pixel RGB: {pixel}") # 打印RGB值,注意这里是BGR顺序,但因为我们用的是Pillow显示,所以已经是RGB顺序了。
# 注意:如果要保持与原始视频帧的一致性(BGR),则应使用pixel[::-1]来获取RGB顺序的元组。
print(f"Clicked pixel BGR: {pixel[::-1]}") # 打印原始BGR顺序的RGB值(如果需要)
"""
def get_rgb_at_mouse(event):
print('进入_获取RGB')
selected_option = radio_var.get()
print('selected_option:',selected_option)
if selected_option == '1':
print('进入_鼠标“点击”获取RGB')
get_rgb_point(event)
elif selected_option == '2':
print('进入_选定“点”获取RGB')
def print_number(number):
get_rgb_point(event)
count21 = entry_c21.get() # 获取输入框内容
count21_int = int(count21)
if number < count21_int-1: # 假设我们想输出10次
threading.Timer(3, print_number, args=[number+1]).start()# 3秒
print_number(0)
elif selected_option == '3':
print('进入_选定“面”获取RGB')
def print_number1(number):
get_rgb_point(event)
count31 = entry_c31.get() # 获取输入框内容
count31_int = int(count31)
if number < count31_int-1: # 假设我们想输出10次
threading.Timer(5, print_number1, args=[number+1]).start() # 5秒
print_number1(0)
else:
print('请选择选取方式')
def get_rgb_point(event):
print('----- 进入_获取RGB -----')
global flag_picture,flag_video
# 获取当前时间
#now = datetime.now()
# 格式化时间
#current_datetime = now.strftime("%Y-%m-%d %H:%M:%S")
#print("当前日期和时间:", current_datetime)
try:
#while True:
# 获取当前鼠标的位置
#xx = int(event.x)
# yy = int(event.y)
#print('xx:',xx,'_yy:',yy)
selected_option = radio_var.get()
print('selected_option:',selected_option)
if selected_option == '1':
x, y = pyautogui.position()
# 截取当前屏幕图像
screenshot = pyautogui.screenshot()
# 获取鼠标位置的 RGB 值
rgb = screenshot.getpixel((x, y))
# 打印 RGB 值
print(f"鼠标位置: ({x}, {y}) -> RGB: {rgb}")
#print('RGB:',rgb,type(rgb))
display_point_item(x,y,rgb)
elif selected_option == '2':
x21 = entry_x21.get() # 获取输入框内容
y21 = entry_y21.get() # 获取输入框内容
x=int(x21)
y=int(y21)
#pyautogui.click(x=x,y=y)
pyautogui.moveTo(x=x,y=y)
#x, y = pyautogui.position()
# 截取当前屏幕图像
screenshot = pyautogui.screenshot()
# 获取鼠标位置的 RGB 值
rgb = screenshot.getpixel((x, y))
# 打印 RGB 值
print(f"鼠标位置: ({x}, {y}) -> RGB: {rgb}")
#print('RGB:',rgb,type(rgb))
display_point_item(x,y,rgb)
elif selected_option == '3':
if flag_picture == 1 and flag_video == 0:
ccc = 40
else:
ccc = 0
#print('3333')
x1=0
x2=0
x3=0
x4=0
y1=0
y2=0
y3=0
y4=0
x31 = entry_x31.get() # 获取输入框内容
y31 = entry_y31.get() # 获取输入框内容
x1=int(x31)-25 # 方框点
y1=int(y31)-25
## 第1点 ##
pyautogui.moveTo(x=x1,y=y1)
#pyautogui.moveRel(100,500,duration=4)
# 第一个参数是左右移动像素值,第二个是上下移动像素值
#pyautogui.moveRel(x,y,duration=4)
# 截取当前屏幕图像
screenshot = pyautogui.screenshot()
# 获取鼠标位置的 RGB 值
rgb1 = screenshot.getpixel((x1, y1))
# 打印 RGB 值
#print(f"鼠标位置: ({x}, {y}) -> RGB: {rgb}")
#print('RGB1:',rgb1,type(rgb1))
## 第2点 ##
x2=x1+50 # 方框点
y2=y1
pyautogui.moveTo(x=x2,y=y2)
screenshot = pyautogui.screenshot()
rgb2 = screenshot.getpixel((x2, y2))
#print('RGB2:',rgb2,type(rgb2))
## 第3点 ##
x3=int(x31)+25 # 方框点
y3=int(y31)+25 # 方框点
pyautogui.moveTo(x=x3,y=y3)
screenshot = pyautogui.screenshot()
rgb3 = screenshot.getpixel((x3, y3))
#print('RGB3:',rgb3,type(rgb3))
## 第4点 ##
x4=x1
y4=y1+50 # 方框点
pyautogui.moveTo(x=x4,y=y4)
screenshot = pyautogui.screenshot()
rgb4 = screenshot.getpixel((x4, y4))
#print('RGB4:',rgb4,type(rgb4))
## 第5点 ##
x5=int(x31) # 方框点中心
y5=int(y31) # 方框点中心
pyautogui.moveTo(x=x5,y=y5)
screenshot = pyautogui.screenshot()
rgb5 = screenshot.getpixel((x5, y5))
#print('RGB5:',rgb5,type(rgb5))
rgb1_list = list(rgb1)
rgb2_list = list(rgb2)
rgb3_list = list(rgb3)
rgb4_list = list(rgb4)
rgb5_list = list(rgb5)
#print('1:',int(rgb1_list[0]))
#print('2:',int(rgb2_list[0]))
#print('3:',int(rgb3_list[0]))
#print('4:',int(rgb4_list[0]))
#print('5:',int(rgb5_list[0]))
r_avg =(int(rgb1_list[0]) +int(rgb2_list[0]) +int(rgb3_list[0]) +int(rgb4_list[0]) +int(rgb5_list[0]) )/5
g_avg =(int(rgb1_list[1]) +int(rgb2_list[1]) +int(rgb3_list[1]) +int(rgb4_list[1]) +int(rgb5_list[1]) )/5
b_avg =( int(rgb1_list[2]) +int(rgb2_list[2]) +int(rgb3_list[2]) +int(rgb4_list[2]) +int(rgb5_list[2]) )/5
rgb_list = []
rgb_list.append(int(r_avg))
rgb_list.append(int(g_avg))
rgb_list.append(int(b_avg))
x=x5
y=y5
rgb=tuple(rgb_list)
#print('rgb:',rgb,type(rgb))
# 截取当前屏幕图像
#screenshot = pyautogui.screenshot()
# 获取鼠标位置的 RGB 值
#rgb = screenshot.getpixel((x, y))
# 打印 RGB 值
print(f"鼠标位置: ({x}, {y}) -> RGB: {rgb}")
#print('RGB:',rgb,type(rgb))
display_point_item(x,y,rgb)
# 暂停一段时间,避免过于频繁的输出
#time.sleep(0.5)
except KeyboardInterrupt:
print("\n程序已结束。")
def display_point_item(x,y,rgb):
#print('x_y_rgb:',x,'_',y,'_',rgb)
### 显示RGB ###
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
#text_11 =str(xx)
text_11 =str(x)
label_item_11.configure(text=text_11)
#text_12 =str(yy)
text_12 =str(y)
label_item_12.configure(text=text_12)
text_13 =str(rgb[0])
label_item_13.configure(text=text_13)
text_14 =str(rgb[1])
label_item_14.configure(text=text_14)
text_15 =str(rgb[2])
label_item_15.configure(text=text_15)
r=int(text_13)
g=int(text_14)
b=int(text_15)
elif selected_option == '2':
"""
text_11 =str(x)
label_item_11.configure(text=text_11)
#text_12 =str(yy)
text_12 =str(y)
label_item_12.configure(text=text_12)
"""
text_23 =str(rgb[0])
label_item_23.configure(text=text_23)
text_24 =str(rgb[1])
label_item_24.configure(text=text_24)
text_25 =str(rgb[2])
label_item_25.configure(text=text_25)
r=int(text_23)
g=int(text_24)
b=int(text_25)
elif selected_option == '3':
"""
text_11 =str(x)
label_item_11.configure(text=text_11)
#text_12 =str(yy)
text_12 =str(y)
label_item_12.configure(text=text_12)
"""
text_33 =str(rgb[0])
label_item_33.configure(text=text_33)
text_34 =str(rgb[1])
label_item_34.configure(text=text_34)
text_35 =str(rgb[2])
label_item_35.configure(text=text_35)
r=int(text_33)
g=int(text_34)
b=int(text_35)
#print('r1_g1_b1:',r,'_',g,'_',b,'_')
temp_data_calculate(x,y,r,g,b)
def temp_data_calculate(x,y,r,g,b):
file_path = 'temp_data_spec.txt' # TXT文件路径
#read_txt_file(file_path)
temp_spec = []
with open(file_path, 'r') as file:
for line in file:
parts = line.strip().split(',')
if len(parts) == 6:
temp_spec.append((parts[0], parts[1],parts[2],parts[3],parts[4],parts[5]))
#print('temp_spec1:',temp_spec)
#r=249
#g=100
#b=100
#print('rgb:',r,'-',g,'-',b)
list_1 = []
list_2 = []
list_a=[]
list_b=[]
del temp_spec[0]
#print('temp_spec2:',temp_spec)
temp_spec_list = []
i=0
while i<len(temp_spec):
temp_spec_list_0 = []
temp_spec_list_0.append(temp_spec[i][0]) # 序号
temp_spec_list_0.append(temp_spec[i][1]) # 温度标准
temp_spec_list_0.append(str(int(temp_spec[i][3])+int(temp_spec[i][4])/1000+int(temp_spec[i][5])/(1000*1000))) # 色度标准折算
temp_spec_list.append(temp_spec_list_0)
i=i+1
#print('temp_spec_list:',temp_spec_list)
rgb_real_data = int(r)+int(g)/1000+int(b)/(1000*1000)
print('rgb_real_data:',rgb_real_data)
rgb_real_data_str = str(rgb_real_data) # 色度实时值 折算
#print('rgb_real_data_str:',rgb_real_data_str)
if rgb_real_data < float(temp_spec_list[-1][2]):
print('低于标准最小值')
temp_real_data = float(temp_spec_list[-1][1]) * rgb_real_data / float(temp_spec_list[-1][2])
elif rgb_real_data == float(temp_spec_list[-1][2]):
print('等于标准最小值')
temp_real_data = float(temp_spec_list[-1][1])
elif rgb_real_data > float(temp_spec_list[0][2]):
print('高于标准最大值')
temp_real_data = float(temp_spec_list[0][1]) * rgb_real_data / float(temp_spec_list[0][2])
elif rgb_real_data == float(temp_spec_list[0][2]):
print('等于标准最大值')
temp_real_data = float(temp_spec_list[0][1])
else:
print('在最小值-最大值之间')
"""
i=0
while i <len(temp_spec_list):
print('float(rgb_real_data_str) :',float(rgb_real_data_str) )
print('float(temp_spec_list[i][2]) :',float(temp_spec_list[i][2]))
if float(rgb_real_data_str) == float(temp_spec_list[i][2]):
print('111')
temp_real_data = temp_spec_list[i][1]
i=i+1
"""
#print('222')
a=0
list_a = []
while a < len(temp_spec_list):
if float(rgb_real_data_str) < float(temp_spec_list[a][2]):
#print('lower')
list_a.append(temp_spec_list[a]) # 所有大于实际值的数值
#print('list_a:',list_a)
a=a+1
temp_spec_higher = list_a[-1] # 最后1个,为上限值
print('======temp_spec_higher:',temp_spec_higher)
c=0
while c<len(temp_spec_list):
#print('temp_data[c][3]:',temp_data[i][3])
if (int(temp_spec_higher[0])+1) == int(temp_spec_list[c][0]): # 上限值+1,为下限值
temp_spec_lower_0 = temp_spec_list[c]
c=c+1
temp_spec_lower = list(temp_spec_lower_0)
print('======temp_spec_lower:',temp_spec_lower)
rgb_spec_data_lower = float(temp_spec_lower[2])
rgb_spec_data_higher = float(temp_spec_higher[2])
temp_spec_data_lower = float(temp_spec_lower[1])
temp_spec_data_higher = float(temp_spec_higher[1])
data_middle = (float(rgb_real_data_str)-rgb_spec_data_lower)/(rgb_spec_data_higher-rgb_spec_data_lower)
temp_real_data = (temp_spec_data_higher - temp_spec_data_lower)*data_middle+temp_spec_data_lower
print('temp_real_data:',temp_real_data)
temp_display(x,y,r,g,b,temp_real_data)
def temp_display(x,y,r,g,b,temp_real_data):
print('进入_温度显示')
#global tree
### 显示温度值 ###
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
text_16 =str(int(temp_real_data))
label_item_16.configure(text=text_16)
elif selected_option == '2':
text_26 =str(int(temp_real_data))
label_item_26.configure(text=text_26)
if selected_option == '3':
text_36 =str(int(temp_real_data))
label_item_36.configure(text=text_36)
temp_spec_lower = (entry_lower11.get()) # 获取输入框内容
temp_spec_higher = (entry_higher11.get()) # 获取输入框内容
print('temp_spec_lower:',temp_spec_lower)
temp_spec_higher_int = int(temp_spec_higher)
temp_spec_lower_int = int(temp_spec_lower)
flag_lower = 0
flag_higher = 0
if temp_real_data < temp_spec_lower_int :
print('温度低异常')
flag_lower = 1
### 显示判定值&报警 ###
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
text_17 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_17.configure(bg='white',fg='red',text=text_17)
text_18 ='温度低'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_18.configure(bg='red',fg='white',text=text_18)
label_topic_4.configure(bg='red',fg='white',text='温度偏低')
elif selected_option == '2':
text_27 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_27.configure(bg='white',fg='red',text=text_27)
text_28 ='温度低'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_28.configure(bg='red',fg='white',text=text_28)
label_topic_4.configure(bg='red',fg='white',text='温度偏低')
elif selected_option == '3':
text_37 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_37.configure(bg='white',fg='red',text=text_37)
text_38 ='温度低'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_38.configure(bg='red',fg='white',text=text_38)
label_topic_4.configure(bg='red',fg='white',text='温度偏低')
#messagebox.showwarning(title = "异常!", message="温度偏低......")
# 播放系统默认警告声音
#winsound.Beep(1000, 1000) # 频率为1000Hz,时长为1000毫秒
elif temp_real_data > temp_spec_higher_int:
print('温度高异常')
flag_higher = 1
### 显示判定值&报警 ###
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
text_17 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_17.configure(bg='white',fg='red',text=text_17)
text_18 ='温度高'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_18.configure(bg='red',fg='white',text=text_18)
label_topic_4.configure(bg='red',fg='white',text='温度偏高')
elif selected_option == '2':
text_27 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_27.configure(bg='white',fg='red',text=text_27)
text_28 ='温度高'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_28.configure(bg='red',fg='white',text=text_28)
label_topic_4.configure(bg='red',fg='white',text='温度偏高')
elif selected_option == '3':
text_37 ='异常'
#label_item_17.configure(bg='white',fg='red',text='异常')
#label_item_37.configure(bg='white',fg='red',text=text_37)
text_38 ='温度高'
#label_item_18.configure(bg='red',fg='white',text='报警')
label_item_38.configure(bg='red',fg='white',text=text_38)
label_topic_4.configure(bg='red',fg='white',text='温度偏高')
else:
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
print('温度正常')
text_17 ='正常'
#label_item_17.configure(bg='white',fg='green',text=text_17)
text_18 ='正常'
label_item_18.configure(bg='green',fg='white',text=text_18)
label_topic_4.configure(bg='green',fg='white',text='温度正常')
elif selected_option == '2':
print('温度正常')
text_27 ='正常'
#label_item_27.configure(bg='white',fg='green',text=text_27)
text_28 ='正常'
label_item_28.configure(bg='green',fg='white',text=text_28)
label_topic_4.configure(bg='green',fg='white',text='温度正常')
elif selected_option == '3':
print('温度正常')
text_37 ='正常'
#label_item_37.configure(bg='white',fg='green',text=text_37)
text_38 ='正常'
label_item_38.configure(bg='green',fg='white',text=text_38)
label_topic_4.configure(bg='green',fg='white',text='温度正常')
data_ttl = []
data_ttl_0 = []
# 获取当前时间
now = datetime.now()
# 格式化时间
current_datetime = now.strftime("%Y-%m-%d %H:%M:%S")
print("当前日期和时间:", current_datetime)
global point_count
point_count = point_count+1
data_ttl_0.append(str(point_count))
data_ttl_0.append(str(current_datetime))
data_ttl_0.append(str(x))
data_ttl_0.append(str(y))
data_ttl_0.append(str(r))
data_ttl_0.append(str(g))
data_ttl_0.append(str(b))
data_ttl_0.append(str(int(temp_real_data)))
data_ttl_0.append(str(temp_spec_lower))
data_ttl_0.append(str(temp_spec_higher))
selected_option = radio_var.get()
#print('selected_option:',selected_option)
if selected_option == '1':
#data_ttl_0.append(str(text_17))
data_ttl_0.append(str(text_18))
elif selected_option == '2':
#data_ttl_0.append(str(text_27))
data_ttl_0.append(str(text_28))
elif selected_option == '3':
#data_ttl_0.append(str(text_37))
data_ttl_0.append(str(text_38))
data_ttl.append(data_ttl_0)
print('data_ttl:',data_ttl)
# 插入数据项
for item in data_ttl:
tree.insert('', '0', values=item)
#tree.insert('', 'end', values=item)
"""
# 获取第一列的所有数据
for item in tree.get_children():
date_tree = tree.item(item, 'values') # 获取第一列的值
print('date_tree:',date_tree)
"""
date_tree = []
data_tree = []
count_tree = []
for item in tree.get_children():
count_tree_0 = tree.set(item, 'c1') # 获取第一列的值
count_tree.append(int(count_tree_0))
#print('count_tree:',count_tree)
for item in tree.get_children():
date_tree_0 = tree.set(item, 'c2') # 获取第一列的值
date_tree.append(date_tree_0)
#print('date_tree:',date_tree)
# 获取第一列的所有数据
for item in tree.get_children():
data_tree_0 = tree.set(item, 'c8') # 获取第一列的值
data_tree.append(int(data_tree_0))
#print('data_tree:',data_tree)
plot_curve(count_tree,date_tree,data_tree)
if selected_option == '1' and flag_higher == 1:
# 播放系统默认警告声音
winsound.Beep(1000, 1000) # 频率为1000Hz,时长为1000毫秒
messagebox.showwarning(title = "异常!", message="温度偏高......")
if selected_option == '1' and flag_lower == 1:
# 播放系统默认警告声音
winsound.Beep(1000, 1000) # 频率为1000Hz,时长为1000毫秒
messagebox.showwarning(title = "异常!", message="温度偏低......")
elif selected_option == '2' and flag_lower == 1:
#messagebox.showwarning(title = "异常!", message="温度偏低......")
# 播放系统默认警告声音
winsound.Beep(500, 500) # 频率为1000Hz,时长为1000毫秒
elif selected_option == '2' and flag_higher == 1:
#messagebox.showwarning(title = "异常!", message="温度偏低......")
# 播放系统默认警告声音
winsound.Beep(500, 500) # 频率为1000Hz,时长为1000毫秒
elif selected_option == '3' and flag_lower == 1:
#messagebox.showwarning(title = "异常!", message="温度偏低......")
# 播放系统默认警告声音
winsound.Beep(500, 500) # 频率为1000Hz,时长为1000毫秒
elif selected_option == '3' and flag_higher == 1:
#messagebox.showwarning(title = "异常!", message="温度偏低......")
# 播放系统默认警告声音
winsound.Beep(500, 500) # 频率为1000Hz,时长为1000毫秒
def plot_curve(count_tree,date_tree,data_tree):
print('进入_曲线绘图')
global output, fig
output = None
x = count_tree
y= data_tree
fig = Figure(figsize=(6.4, 3.1), dpi=100)
# adding the subplot
plot1 = fig.add_subplot(111)
# plotting the graph
#plot1.plot(x,y_higher,'ro-', label='H_Line', markersize=1)
plot1.plot(x,y, 'bo-', label='Value',markersize=5)
#plot1.plot(x,y_lower,'ro-', label='L_Line', markersize=1)
# 添加图例
plot1.legend()
# 设置字体,避免出现方块
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
# 设置图表标题和坐标轴标签
#plot1.set_title('变化趋势图', fontsize=14)
plot1.set_xlabel('序号')
plot1.set_ylabel('数值')
#plot1.set_rotation(180)
#plot1.set_xticks(fontname='Times New Roman', fontsize=14)
#plot1.set_yticks(fontname='Times New Roman', fontsize=14)
output = FigureCanvasTkAgg(fig, master=canvas2)
print('FigureCanvasTkAgg:',FigureCanvasTkAgg)
#messagebox.showinfo("提示", "绘图中,请稍后......")
output.draw()
output.get_tk_widget().place(x=0, y=0)
def clear_video_plot():
count_tree =[]
date_tree=[]
data_tree=[]
plot_curve(count_tree,date_tree,data_tree)
tree.delete(*tree.get_children())
global point_count
point_count=0
def page_to_main():
print('page_to_main')
#window_video.place_forget()
window_video.iconify() # 最小化窗口
#self.open_window_sql()
def page_to_sql():
print('page_to_sql')
#window_video.iconify() # 最小化窗口
window_video.destroy()
NewWindow_sql(master)
#self.open_window_sql()
# 连接到MySQL数据库
def connect_to_database():
return mysql.connector.connect(
host="localhost",
user="root",
password="123456",
database="pic_temp"
)
# 将Treeview中的数据保存到数据库
def save_to_database():
print('进入_保存数据到Mysql')
# 连接到数据库并保存数据到数据库的按钮
conn = connect_to_database()
database_name = "pic_temp"
cursor = conn.cursor()
items = tree.get_children()
flag_save_ok = 0
for item in items[::-1] : # 从 tree 最后1条开始读取
values = tree.item(item, 'values')
#print('values:',values)
try:
query = "SELECT COUNT(*) FROM temp_real WHERE date = %s" # 查询测试记录是否存在,避免重复保存
cursor.execute(query, (values[1],))
results = cursor.fetchone()[0]
if results == 0:
sql_01 = "INSERT INTO temp_real (date, x,y,r,g,b,temp,lower,higher,alarm) "+\
"VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
cursor.execute(sql_01, (values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], values[10]))
conn.commit() # 提交更改到数据库
flag_save_ok = 1
else:
flag_save_ok = 2
print("数据重复保存!")
messagebox.showinfo("提示", "数据重复保存!")
except mysql.connector.Error as err:
print("Error: ", err)
flag_save_ok = 0
conn.rollback()
if flag_save_ok == 1:
print("保存数据库完成!")
messagebox.showinfo("提示", "保存数据库完成!\n数据表名:"+database_name)
elif flag_save_ok == 0:
print("保存数据库异常!")
messagebox.showinfo("提示", "保存数据库异常!\n异常名:"+err)
cursor.close()
conn.close()
def output_excel():
#global tree
print('进入_导出数据到EXCEL')
#file_path = filedialog.asksaveasfilename(defaultextension='.xlsx')
#if file_path:
# 获取所有行数据
records = tree.get_children()
data = [tree.item(r)['values'] for r in records]
df = pd.DataFrame(data, columns=['序号', '时间', 'X','Y', 'R', 'G', 'B','温度', '下限', '上限','报警'])
# 获取当前时间
now = datetime.now()
# 格式化时间
current_datetime = now.strftime("%Y%m%d_%H%M%S")
print("当前日期和时间:", current_datetime)
# 将DataFrame导出到Excel文件
file_path = 'Temp_output_'+str(current_datetime)+'.xlsx'
df.to_excel(file_path, index=False)
print("导出Excel完成!")
messagebox.showinfo("提示", "导出Excel完成!\n文件名:"+file_path)
#else:
#print("未选择保存文件路径")
#messagebox.showinfo("提示", "未选择保存文件路径!")
### 界面 ###
path = StringVar()
### 左侧 ###
#radio_button_camera = tk.Radiobutton(window_video, text="摄像头",variable=radio_var_path, value="1",font=('宋体', 11))
#radio_button1.place(x=30, y=80)
#radio_button_pic = tk.Radiobutton(window_video, text="照片图像",variable=radio_var_path, value="2",font=('宋体', 11))
#radio_button1.place(x=30, y=130)
label_topic_2 = Label(window_video, text="照片图像", font=('宋体', 18))
label_topic_2.place(x=30, y=130)
#button_camera_open = tk.Button(window_video, text="开启\n摄像头", command=open_camera,width=5, height=2)
#button_camera_open.place(x=10, y=120)
button_select = tk.Button(window_video, text="选择\n文件", command=select_file,width=5, height=2)
button_select.place(x=150, y=120)
label_path=tk.Label(window_video,text = "目标路径:",width=10, height=2)
label_path.place(x=200, y=110)
entry_path=tk.Entry(window_video, textvariable = path,width=25, font=('宋体', 10))
entry_path.place(x=200, y=145)
button_play = tk.Button(window_video, text="显示\n画面", command=play_display,width=5, height=2)
button_play.place(x=390, y=120)
button_camera_open = tk.Button(window_video, text="开启\n摄像头", command=open_camera,width=5, height=2)
button_camera_open.place(x=450, y=120)
button_stop = tk.Button(window_video, text="停止\n播放", command=stop_play,width=5, height=2)
button_stop.place(x=500, y=120)
button_camera_save = tk.Button(window_video, text="录制\n视频", command=record_camera,width=5, height=2)
button_camera_save.place(x=550, y=120)
button_camera_stop = tk.Button(window_video, text="关闭\n摄像头", command=close_camera,width=5, height=2)
button_camera_stop.place(x=600, y=120)
width = 630
height = 300 # 调整窗口大小以适应视频
canvas1 = tk.Canvas(window_video, width=630, height=300,bg='lightgreen')
canvas1.place(x=10, y=185)
#canvas1.bind("<Button-1>", on_canvas1_click)
canvas1.bind("<Button-1>", get_rgb_at_mouse)
### 第0行 ###
label_item_01 = Label(window_video, text="选择方式", font=('宋体', 11))
label_item_01.place(x=10, y=500)
label_item_0B = Label(window_video, text="次数", font=('宋体', 11))
label_item_0B.place(x=90, y=500)
label_item_07 = Label(window_video, text="X", font=('宋体', 11))
label_item_07.place(x=150, y=500)
label_item_08 = Label(window_video, text="Y", font=('宋体', 11))
label_item_08.place(x=200, y=500)
label_item_09 = Label(window_video, text="R", font=('宋体', 11))
label_item_09.place(x=250, y=500)
label_item_10 = Label(window_video, text="G", font=('宋体', 11))
label_item_10.place(x=300, y=500)
label_item_0A = Label(window_video, text="B", font=('宋体', 11))
label_item_0A.place(x=350, y=500)
label_item_02 = Label(window_video, text="温度", font=('宋体', 11))
label_item_02.place(x=400, y=500)
label_item_03 = Label(window_video, text="下限值", font=('宋体', 11))
label_item_03.place(x=470, y=500)
label_item_04 = Label(window_video, text="上限值", font=('宋体', 11))
label_item_04.place(x=540, y=500)
#label_item_05 = Label(window_video, text="数据质量", font=('宋体', 11))
#label_item_05.place(x=710, y=500)
label_item_06 = Label(window_video, text="报警", font=('宋体', 11))
label_item_06.place(x=610, y=500)
#label_item_11 = Label(window, text="温度1", font=('宋体', 12))
#label_item_11.place(x=250, y=700)
### 第1行 ###
label_item_1B = Label(window_video, text="1", font=('宋体', 11))
label_item_1B.place(x=90, y=550)
label_item_11 = Label(window_video, text="X1", font=('宋体', 11))
label_item_11.place(x=150, y=550)
label_item_12 = Label(window_video, text="Y1", font=('宋体', 11))
label_item_12.place(x=200, y=550)
label_item_13 = Label(window_video, text="R1", font=('宋体', 11))
label_item_13.place(x=250, y=550)
label_item_14 = Label(window_video, text="G1", font=('宋体', 11))
label_item_14.place(x=300, y=550)
label_item_15 = Label(window_video, text="B1", font=('宋体', 11))
label_item_15.place(x=350, y=550)
label_item_16 = Label(window_video, text="温度1", font=('宋体', 11))
label_item_16.place(x=400, y=550)
entry_lower11= Entry(window_video, width=5, font=('宋体', 11))
entry_lower11.place(x=470, y=550)
entry_lower11.insert(0, "48")
entry_higher11 = Entry(window_video, width=5, font=('宋体', 11))
entry_higher11.place(x=540, y=550)
entry_higher11.insert(0, "58")
#label_item_17 = Label(window_video, text="数据质量", font=('宋体', 11))
#label_item_17.place(x=750, y=550)
label_item_18 = Label(window_video, text="报警", font=('宋体', 11))
label_item_18.place(x=610, y=550)
#label_item_21 = Label(window, text="温度2", font=('宋体', 12))
#label_item_21.place(x=250, y=750)
### 第2行 ###
entry_c21 = Entry(window_video, width=5, font=('宋体', 11))
entry_c21.place(x=90, y=600)
entry_c21.insert(0, "3")
entry_x21 = Entry(window_video, width=5, font=('宋体', 11))
entry_x21.place(x=150, y=600)
entry_x21.insert(0, "410")
entry_y21 = Entry(window_video, width=5, font=('宋体', 11))
entry_y21.place(x=200, y=600)
entry_y21.insert(0, "490")
label_item_23 = Label(window_video, text="R2", font=('宋体', 11))
label_item_23.place(x=250, y=600)
label_item_24 = Label(window_video, text="G2", font=('宋体', 11))
label_item_24.place(x=300, y=600)
label_item_25 = Label(window_video, text="B2", font=('宋体', 11))
label_item_25.place(x=350, y=600)
label_item_26 = Label(window_video, text="温度2", font=('宋体', 11))
label_item_26.place(x=400, y=600)
entry_lower22 = Entry(window_video,width=5, font=('宋体', 11))
entry_lower22.place(x=470, y=600)
entry_lower22.insert(0, "48")
entry_higher22 = Entry(window_video, width=5, font=('宋体', 11))
entry_higher22.place(x=540, y=600)
entry_higher22.insert(0, "58")
#label_item_27 = Label(window_video, text="数据质量", font=('宋体', 11))
#label_item_27.place(x=750, y=600)
label_item_28 = Label(window_video, text="报警", font=('宋体', 11))
label_item_28.place(x=610, y=600)
### 第3行 ###
entry_c31 = Entry(window_video, width=5, font=('宋体', 11))
entry_c31.place(x=90, y=650)
entry_c31.insert(0, "3")
entry_x31 = Entry(window_video, width=5, font=('宋体', 11))
entry_x31.place(x=150, y=650)
entry_x31.insert(0, "410")
entry_y31 = Entry(window_video, width=5, font=('宋体', 11))
entry_y31.place(x=200, y=650)
entry_y31.insert(0, "490")
label_item_33 = Label(window_video, text="R3", font=('宋体', 11))
label_item_33.place(x=250, y=650)
label_item_34 = Label(window_video, text="G3", font=('宋体', 11))
label_item_34.place(x=300, y=650)
label_item_35 = Label(window_video, text="B3", font=('宋体', 11))
label_item_35.place(x=350, y=650)
label_item_36 = Label(window_video, text="温度3", font=('宋体', 11))
label_item_36.place(x=400, y=650)
entry_lower32 = Entry(window_video, width=5, font=('宋体', 11))
entry_lower32.place(x=470, y=650)
entry_lower32.insert(0, "48")
entry_higher32 = Entry(window_video, width=5, font=('宋体', 11))
entry_higher32.place(x=540, y=650)
entry_higher32.insert(0, "58")
#label_item_37 = Label(window_video, text="数据质量", font=('宋体', 11))
#label_item_37.place(x=750, y=650)
label_item_38 = Label(window_video, text="报警", font=('宋体', 11))
label_item_38.place(x=610, y=650)
### 第4行 ###
label_item_41 = Label(window_video, text="方框", font=('宋体', 11))
label_item_41.place(x=90, y=675)
entry_x41 = Entry(window_video, width=5, font=('宋体', 11))
entry_x41.place(x=150, y=675)
entry_x41.insert(0, "300")
entry_y41 = Entry(window_video, width=5, font=('宋体', 11))
entry_y41.place(x=200, y=675)
entry_y41.insert(0, "250")
# 单选框
radio_var = tk.StringVar() # 创建一个StringVar变量,用于存储选中的值
radio_var.set('1')
#radio_var.set(None)
# 创建第一个单选框
radio_button1 = tk.Radiobutton(window_video, text="任意点",variable=radio_var, value="1",font=('宋体', 11))
radio_button1.place(x=10, y=545)
# 创建第二个单选框
radio_button2 = tk.Radiobutton(window_video, text="选定点",variable=radio_var, value="2",font=('宋体', 11))
radio_button2.place(x=10, y=595)
# 创建第三个单选框
radio_button3 = tk.Radiobutton(window_video, text="选定面",variable=radio_var, value="3",font=('宋体', 11))
radio_button3.place(x=10, y=645)
### 右侧 ###
label_topic_3 = Label(window_video, text="数据曲线", font=('宋体', 18))
label_topic_3.place(x=750, y=130)
label_topic_4 = Label(window_video, text="设备状况", font=('宋体', 18))
label_topic_4.place(x=950, y=130)
button_clear = tk.Button(window_video, text="清除\n数据", command=clear_video_plot,width=5, height=2)
#button_clear.place(x=900, y=680)
button_clear.place(x=1100, y=120)
button_clear = tk.Button(window_video, text="保存到\n数据库", command=save_to_database,width=5, height=2)
#button_clear.place(x=900, y=680)
button_clear.place(x=1150, y=120)
button_clear = tk.Button(window_video, text="导出到\nExcel", command=output_excel,width=5, height=2)
#button_clear.place(x=900, y=680)
button_clear.place(x=1200, y=120)
canvas2 = tk.Canvas(window_video, width=630, height=300,bg='lightyellow')
canvas2.place(x=650, y=185)
# 列表
# 创建Treeview控件
tree = ttk.Treeview(window_video, columns=('c1','c2', 'c3', 'c4', 'c5', 'c6', 'c7','c8','c9','c10','c11'), show='headings')
# 创建滚动条
scrollbar = ttk.Scrollbar(window_video, orient="vertical", command=tree.yview)
tree.configure(yscrollcommand=scrollbar.set)
# 放置Treeview到窗口中
tree.place(x=680, y=500, width=590, height=180) # 在窗口的特定位置放置
# 将滚动条与树形控件关联
#tree.place(x=0, y=0, relwidth=1, relheight=1) # 让树形控件填满整个窗口
#scrollbar.place(x=375, y=0, relheight=1) # 将滚动条放置在右侧,宽度固定为25像素(可根据需要调整)
scrollbar.place(x=1270, y=500,height=180) # 将滚动条放置在右侧,宽度固定为25像素(可根据需要调整)
tree.column('c1', width=30, minwidth=30) # 配置第1列的宽度和最小宽度
tree.column('c2', width=130, minwidth=130) # 配置第2列的宽度和最小宽度
tree.column('c3', width=30, minwidth=30) # 配置第3列的宽度和最小宽度
tree.column('c4', width=30, minwidth=30) # 配置第4列的宽度和最小宽度
tree.column('c5', width=30, minwidth=30) # 配置第5列的宽度和最小宽度
tree.column('c6', width=30, minwidth=30) # 配置第6列的宽度和最小宽度
tree.column('c7', width=30, minwidth=30) # 配置第7列的宽度和最小宽度
tree.column('c8', width=30, minwidth=30) # 配置第8列的宽度和最小宽度
tree.column('c9', width=30, minwidth=30) # 配置第9列的宽度和最小宽度
tree.column('c10', width=30, minwidth=30) # 配置第10列的宽度和最小宽度
#tree.column('c11', width=30, minwidth=30) # 配置第11列的宽度和最小宽度
tree.column('c11', width=30, minwidth=30) # 配置第12列的宽度和最小宽度
# 设置列标题
tree.heading('c1', text='序号')
tree.heading('c2', text='时间')
tree.heading('c3', text='X')
tree.heading('c4', text='Y')
tree.heading('c5', text='R')
tree.heading('c6', text='G')
tree.heading('c7', text='B')
tree.heading('c8', text='温度')
tree.heading('c9', text='下限')
tree.heading('c10', text='上限')
#tree.heading('c11', text='质量')
tree.heading('c11', text='报警')
window_video.mainloop()
if __name__ == "__main__":
# 创建主窗口实例
root = tk.Tk()
app = MainWindow(root)
#root.geometry("1550x800+150+150")
root.geometry("510x650+600+150")
root.mainloop()
帮我解析各部分代码的功能