init: UI design basically completed

This commit is contained in:
gitea 2025-01-01 13:20:39 +08:00
commit d9f898715e
6 changed files with 270 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
test.py
.idea/
.venv/
assets/logdata/
package/

BIN
assets/media/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@ -0,0 +1,43 @@
# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(0, 2, 1, 1),
prodvers=(0, 2, 1, 1),
# Contains a bitmask that specifies the valid bits 'flags'r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
'040904b0',
[StringStruct('CompanyName', 'Rokae - https://www.rokae.com/'),
StringStruct('FileDescription', 'All in one automatic toolbox'),
StringStruct('FileVersion', '0.2.1.1 (2024-12-16)'),
StringStruct('InternalName', 'AIO.exe'),
StringStruct('LegalCopyright', '© 2024-2024 Manford Fan'),
StringStruct('OriginalFilename', 'AIO.exe'),
StringStruct('ProductName', 'AIO'),
StringStruct('ProductVersion', '0.2.1.1 (2024-12-16)')])
]),
VarFileInfo([VarStruct('Translation', [1033, 1200])])
]
)

1
assets/version/vers Normal file
View File

@ -0,0 +1 @@
0.2.1.1@12/16/2024

215
code/common/aio.py Normal file
View File

@ -0,0 +1,215 @@
# from tkinter import colorchooser
# from tkinter import font
# import tkinter as tk
# import threading
# import logging
# import time
# import os
import customtkinter as ctk
from tkinter import messagebox
from tkinter import filedialog
from tkinter import ttk
class App:
def __init__(self):
# ========================================================================
self.root = ctk.CTk()
self.__set_root()
# ========================================================================
# self.style = ttk.Style()
# self.style.configure("nb.TNotebook", font=("Consolas", 28, "normal"))
self.entry_path_dpv = ctk.StringVar()
self.entry_path_dpv.set("数据文件夹路径")
self.entry_path_atv = ctk.StringVar()
self.entry_path_atv.set("数据文件夹路径")
self.entry_ip_atv = ctk.StringVar()
self.entry_ip_atv.set("192.168.0.160")
# ========================================================================
self.frame_left = ctk.CTkFrame(self.root, width=80, corner_radius=0, fg_color="#E9E9E9")
# -------
self.tabview_top = ctk.CTkTabview(self.root, width=900, height=180, fg_color="#E9E9E9", border_width=2, anchor="w", command=self.__switch_tab)
self.tabview_top.add("数据处理")
self.tabview_top.add("自动测试")
# -------
self.tabview_bottom = ctk.CTkTabview(self.root, fg_color="#E9E9E9", border_width=2, anchor="w")
self.tabview_bottom.add("输出")
self.tabview_bottom.add("日志")
# -------
self.frame_status = ctk.CTkFrame(self.root, height=30, bg_color="purple")
# ========================================================================
self.label_logo = ctk.CTkLabel(self.frame_left, text="Rokae AIO", font=self.f_logo, text_color="#4F4F4F")
self.btn_start = ctk.CTkButton(self.frame_left, text="开始运行", font=self.f_normal, fg_color='#4F4F4F', command=lambda: print("---"))
self.btn_save_log = ctk.CTkButton(self.frame_left, text="保存日志", font=self.f_normal, fg_color='#4F4F4F', command=lambda: print("---"))
# ========================================================================
self.om_main_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=120, dynamic_resizing=False, values=["INIT", "brake", "current", "iso", "wavelog"], font=self.f_normal, text_color='#3C3C3C', button_color='#7B6B5B', fg_color="#8D8D8D", command=print)
self.om_sub_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=120, dynamic_resizing=False, values=["cycle", "max", "avg"], font=self.f_normal, text_color='#3C3C3C', button_color='#7B6B5B', fg_color="#8D8D8D", command=print)
self.label_path_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="Path", font=self.f_normal)
self.entry_path_dp = ctk.CTkEntry(self.tabview_top.tab("数据处理"), width=80, state="disabled", textvariable=self.entry_path_dpv, font=self.f_entry, text_color="#818181")
self.label_vel_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="Vel", font=self.f_normal)
self.om_vel_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_normal)
self.label_trq_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="Trq", font=self.f_normal)
self.om_trq_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_normal)
self.label_sensor_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="Sensor", font=self.f_normal)
self.om_sensor_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_normal)
self.label_estop_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="Estop", font=self.f_normal)
self.om_estop_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_normal)
self.label_trqh_dp = ctk.CTkLabel(self.tabview_top.tab("数据处理"), width=50, anchor="e", text="TrqH", font=self.f_normal)
self.om_trqh_dp = ctk.CTkOptionMenu(self.tabview_top.tab("数据处理"), width=80, values=["1", "2", "3", "4", "5"], font=self.f_normal)
# ========================================================================
self.om_main_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=120, dynamic_resizing=False, values=["INIT", "brake", "current"], font=self.f_normal, text_color='#3C3C3C', button_color='#7B6B5B', fg_color="#8D8D8D", command=print)
self.om_sub_at = ctk.CTkOptionMenu(self.tabview_top.tab("自动测试"), width=120, dynamic_resizing=False, values=["负载信息", "tool33", "tool66", "tool100", "inertia"], font=self.f_normal, text_color='#3C3C3C', button_color='#7B6B5B', fg_color="#8D8D8D", command=print)
self.label_ip_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), anchor="e", text="IP", font=self.f_normal)
self.entry_ip_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=160, textvariable=self.entry_ip_atv, font=self.f_entry, text_color="#818181")
self.btn_conn = ctk.CTkButton(self.tabview_top.tab("自动测试"), text="连接", width=60, font=self.f_segbtn)
self.progressbar_at = ctk.CTkProgressBar(self.tabview_top.tab("自动测试"), width=160, mode="indeterminate")
self.label_path_at = ctk.CTkLabel(self.tabview_top.tab("自动测试"), width=50, anchor="e", text="Path", font=self.f_normal)
self.entry_path_at = ctk.CTkEntry(self.tabview_top.tab("自动测试"), width=80, state="disabled", textvariable=self.entry_path_atv, font=self.f_entry, text_color="#818181")
self.segbutton_at = ctk.CTkSegmentedButton(self.tabview_top.tab("自动测试"), width=120, dynamic_resizing=False, values=["功能切换", "触发急停", "恢复急停", "待定功能", "功能待定", "机器状态", "告警信息"], font=self.f_segbtn)
# ========================================================================
self.text_output = ctk.CTkTextbox(self.tabview_bottom.tab("输出"), height=10, font=self.f_text)
# ========================================================================
self.segbutton_logs = ctk.CTkSegmentedButton(self.tabview_bottom.tab("日志"), width=200, dynamic_resizing=False, values=["上一页", "实时", "下一页"], font=self.f_segbtn)
self.btn_find = ctk.CTkButton(self.tabview_bottom.tab("日志"), text="查找", width=60, font=self.f_segbtn)
self.entry_keyword = ctk.CTkEntry(self.tabview_bottom.tab("日志"), placeholder_text="[id-level] 查找内容", width=60, font=self.f_segbtn)
self.label_loglevel = ctk.CTkLabel(self.tabview_bottom.tab("日志"), width=60, anchor="e", text="等级", font=self.f_normal)
self.om_loglevel = ctk.CTkOptionMenu(self.tabview_bottom.tab("日志"), width=60, dynamic_resizing=False, values=["DEBUG", "INFO", "WARNING", "ERROR"], font=self.f_normal, text_color='#3C3C3C', button_color='#7B6B5B', fg_color="#8D8D8D", command=print)
self.treeview_logs = ttk.Treeview(self.tabview_bottom.tab("日志"), height=10, columns=("time", "level", "module", "content"))
# ========================================================================
with open("../../assets/version/vers", mode="r", encoding="utf-8") as f_vers:
_version, _update = f_vers.read().split("@")
_text = f" v{_version} Update@{_update}"
self.label_vers = ctk.CTkLabel(self.frame_status, text=_text, bg_color="#C9C9C9", font=self.f_status, anchor="w")
var_tips = ctk.StringVar()
var_tips.set("当前是最新版本!")
self.label_tips = ctk.CTkLabel(self.frame_status, textvariable=var_tips, bg_color="#ABCDEF", font=self.f_status, anchor="e")
# ========================================================================
self.__draw()
def __set_root(self):
self.root.title("AIO - All in one automatic toolbox")
self.root.iconbitmap("../../assets/media/icon.ico")
self.root.configure(fg_color="#E9E9E9")
self.root.geometry(f"1100x500+10+10")
# self.root.resizable(False, False)
# self.root.protocol("WM_DELETE_WINDOW", self.__close_root)
self.f_normal = ("Consolas", 20, "bold")
self.f_entry = ("Consolas", 18, "bold")
self.f_segbtn = ("楷体", 20, "bold")
self.f_logo = ("Segoe Script Bold", 28, "bold")
self.f_text = ("仿宋", 16, "normal")
self.f_status = ("Consolas", 12, "bold")
def __close_root(self):
msg = "相关数据可能未保存,正在运行程序时有概率会损坏数据文件,确定要终止程序运行吗?"
res = messagebox.askyesno(title="退出程序", message=msg, default=messagebox.NO, icon=messagebox.WARNING)
if res:
self.root.destroy()
def __switch_tab(self):
t_name = self.tabview_top.get()
if t_name == "数据处理":
self.tabview_top.configure(height=180)
elif t_name == "自动测试":
self.tabview_top.configure(height=180)
def __draw(self):
def select_path(event):
t_name = self.tabview_top.get()
dir_path = filedialog.askdirectory()
if t_name == "数据处理":
c_origin = self.entry_path_dpv.get()
if dir_path:
self.entry_path_dpv.set(dir_path)
else:
self.entry_path_dpv.set(c_origin)
elif t_name == "自动测试":
c_origin = self.entry_path_atv.get()
if dir_path:
self.entry_path_atv.set(dir_path)
else:
self.entry_path_atv.set(c_origin)
# ========================================================================
self.root.rowconfigure(0, weight=1)
self.root.rowconfigure(1, weight=99)
self.root.columnconfigure(0, weight=1)
self.root.columnconfigure(1, weight=99)
self.frame_left.grid(row=0, column=0, rowspan=2, sticky="news")
self.tabview_top.grid(row=0, column=1, padx=10, pady=5, sticky="news")
self.tabview_bottom.grid(row=1, column=1, padx=10, pady=(0, 10), sticky="news")
self.frame_status.grid(row=2, column=0, columnspan=2, sticky="news")
# ========================================================================
self.frame_left.rowconfigure(list(range(30)), weight=1)
self.frame_left.columnconfigure(0, weight=1)
self.label_logo.grid(row=0, column=0, sticky="new", padx=20, pady=(20, 40))
self.btn_start.grid(row=1, column=0, sticky="new", padx=15, ipady=4)
self.btn_save_log.grid(row=2, column=0, sticky="new", padx=15, ipady=4)
# ========================================================================
# self.tabview_top.tab("数据处理").grid_rowconfigure([0, 1], weight=1)
self.tabview_top.tab("数据处理").grid_columnconfigure(11, weight=1)
self.om_main_dp.grid(row=0, column=0, padx=10)
self.om_sub_dp.grid(row=1, column=0, padx=10, pady=(0, 10))
self.label_path_dp.grid(row=0, column=1, padx=(0, 5), pady=10)
self.entry_path_dp.grid(row=0, column=2, columnspan=10, padx=(0, 10), pady=10, sticky="we")
self.label_vel_dp.grid(row=1, column=1, padx=(0, 5), pady=(0, 10))
self.om_vel_dp.grid(row=1, column=2, padx=(0, 5), pady=(0, 10))
self.label_trq_dp.grid(row=1, column=3, padx=(0, 5), pady=(0, 10))
self.om_trq_dp.grid(row=1, column=4, padx=(0, 5), pady=(0, 10))
self.label_trqh_dp.grid(row=1, column=5, padx=(0, 5), pady=(0, 10))
self.om_trqh_dp.grid(row=1, column=6, padx=(0, 5), pady=(0, 10))
self.label_estop_dp.grid(row=1, column=7, padx=(0, 5), pady=(0, 10))
self.om_estop_dp.grid(row=1, column=8, padx=(0, 5), pady=(0, 10))
self.label_sensor_dp.grid(row=1, column=9, padx=(0, 5), pady=(0, 10))
self.om_sensor_dp.grid(row=1, column=10, padx=(0, 10), pady=(0, 10))
self.entry_path_dp.bind("<Button-1>", select_path)
self.om_main_dp.set("INIT")
self.om_vel_dp.set("1")
self.om_trq_dp.set("2")
self.om_trqh_dp.set("2")
self.om_estop_dp.set("3")
self.om_sensor_dp.set("3")
# ========================================================================
# self.tabview_top.tab("自动测试").grid_rowconfigure([0, 1, 2], weight=1)
self.tabview_top.tab("自动测试").grid_columnconfigure(4, weight=1)
self.om_main_at.grid(row=0, column=0, padx=10, pady=10, sticky="w")
self.om_sub_at.grid(row=1, column=0, padx=10, pady=(0, 10), sticky="w")
self.label_ip_at.grid(row=0, column=1, padx=(0, 10), sticky="e")
self.entry_ip_at.grid(row=0, column=2)
self.btn_conn.grid(row=0, column=3, padx=10)
self.progressbar_at.grid(row=0, column=4, sticky="e")
self.label_path_at.grid(row=1, column=1, padx=(0, 10), sticky="e")
self.entry_path_at.grid(row=1, column=2, columnspan=3, sticky="we")
self.segbutton_at.grid(row=2, column=0, columnspan=5, sticky="we")
self.progressbar_at.start()
self.entry_path_at.bind("<Button-1>", select_path)
# ========================================================================
self.tabview_bottom.tab("输出").grid_rowconfigure(0, weight=1)
self.tabview_bottom.tab("输出").grid_columnconfigure(0, weight=1)
self.text_output.grid(row=0, column=0, padx=0, pady=1, sticky="news")
# ========================================================================
self.tabview_bottom.tab("日志").grid_rowconfigure(1, weight=1)
self.tabview_bottom.tab("日志").grid_columnconfigure(2, weight=1)
self.segbutton_logs.grid(row=0, column=0, padx=10, pady=(0, 10), sticky="w")
self.btn_find.grid(row=0, column=1, padx=(0, 10), pady=(0, 10), sticky="w")
self.entry_keyword.grid(row=0, column=2, padx=0, pady=(0, 10), sticky="we")
self.treeview_logs.grid(row=1, column=0, columnspan=3, padx=0, pady=1, sticky="news")
self.segbutton_logs.set("实时")
# ========================================================================
self.frame_status.rowconfigure(0, weight=1)
self.frame_status.columnconfigure([0, 1], weight=1)
self.label_vers.grid(row=0, column=0, sticky="news")
self.label_tips.grid(row=0, column=1, sticky="news")
# ========================================================================
def show(self):
self.root.mainloop()
if __name__ == "__main__":
aio = App()
aio.show()

6
readme.md Normal file
View File

@ -0,0 +1,6 @@
#### 其他
customtkinter的tabview组件不支持修改字体大小可以参考 [Changing Font of a Tabview](https://github.com/TomSchimansky/CustomTkinter/issues/2296) 进行手动修改源码实现:
a. 运行 `pip show customtkinter`,获取到库的路径
b. 修改.../windows/widgets/ctk_tabview.py
c. 增加 from .font.ctk_font import CTkFont
d. 在大概 78 行的位置,增加 font=CTkFont(family="Consolas", size=18, weight='bold')