Files
SOMEIP/code_generator/backup/tk_main.py
2026-06-09 20:16:47 +08:00

315 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#encoding: utf-8
import threading
import time
import sys
import tkinter as tk
from tkinter import IntVar, StringVar, scrolledtext, ttk, messagebox,filedialog
import stdout as out
import getchipmsg as getchip
import rwexcle as rwsht
import sendemail as smail
import configmail as cfg
class _Main: #调用SysTrayIcon的Demo窗口
def __init__(s):
s.searching_state = False #搜索状态:是否正在搜索
s.running_tk_win = False
s.auto_run_thread = None #
s.SysTrayIcon = None # 判断是否打开系统托盘图标
# def __del__(s):
# s.auto_run_thread.join()
def main(s):
s.running_tk_win = True
#实例化一个窗体
s.win = tk.Tk()
s.win.title("Find Chips") #窗口名
s.setWindowCenter(s.win, 700, 700) #窗口居中,传入窗口句柄和窗口宽高
# #在窗体win中创建一个Notebook并承载以下两个选项卡
# note = ttk.Notebook(win)
# TabMain = ttk.Frame(note,relief="solid",borderwidth=1)
# note.add(TabMain, text = "") #选项卡1
# #TabDB = ttk.Frame(note,relief="solid",borderwidth=1)
# #note.add(TabDB, text = "Database")#选项卡2
# note.pack()
## 以下为Main选项卡
# 第一组 :芯片信息
s.group_chipForm= tk.LabelFrame(s.win, text="chipForm") #创建Frame一组
s.group_chipForm.grid(row=0, column=0, padx=10, pady=10, sticky="w")
s.form_label=tk.Label(s.group_chipForm, text="芯片表格:")
s.form_label.grid(row=0, column=0, padx=10, pady=10, sticky="w") #创建“芯片表格”字样的Label
s.file_path_entry = tk.Entry(s.group_chipForm,text='select a form', width = 50) #创建输入框
s.file_path_entry.grid(row=0, column=1, padx=10, pady=10, sticky="w")
s.select_file_button = tk.Button(s.group_chipForm, text="打开芯片表格自动完成搜索", command=s.open_excle_and_search_chips)
s.select_file_button.grid(row=0, column=2, padx=10, pady=10, sticky="w")
# 第二组 芯片信息显示列表
s.dataTreeview = ttk.Treeview(s.win, column=('1', '2', '3', '4', '5', '6', '7', '8'), show='headings')
#s.dataTreeview.place(x=10, y=10, width=660, height=350)
s.dataTreeview.grid(row=1, column=0, padx=10, pady=10, sticky="w")
s.dataTreeview.column('1', width=80, anchor="center")
s.dataTreeview.column('2', width=80, anchor="center")
s.dataTreeview.column('3', width=80, anchor="center")
s.dataTreeview.column('4', width=80, anchor="center")
s.dataTreeview.column('5', width=80, anchor="center")
s.dataTreeview.column('6', width=80, anchor="center")
s.dataTreeview.column('7', width=80, anchor="center")
s.dataTreeview.column('8', width=80, anchor="center")
# 头显示
s.dataTreeview.heading('1', text='型号/参数')
s.dataTreeview.heading('2', text='品牌')
s.dataTreeview.heading('3', text='需求量')
s.dataTreeview.heading('4', text='需求价格')
s.dataTreeview.heading('5', text='分销商')
s.dataTreeview.heading('6', text='库存')
s.dataTreeview.heading('7', text='价格')
s.dataTreeview.heading('8', text='是否符合需求')
# 显示并刷新数据库列表
s.showAllInfo(s.dataTreeview,None)
# 第三组 :邮件信息
s.group_email= tk.LabelFrame(s.win, text="email") #创建Frame一组
s.group_email.grid(row=2, column=0, padx=10, pady=10, sticky="w")
s.server_addr=tk.Label(s.group_email, text="SMTP服务器地址")
s.server_addr.grid(row=0, column=0, padx=10, pady=10, sticky="w") #创建“SMTP服务器地址”字样的Label
s.server_addr_entry = tk.Entry(s.group_email,text='', width=30) #创建SMTP服务器地址输入框
s.server_addr_entry.grid(row=0, column=1, padx=10, pady=10, sticky="w")
s.server_port=tk.Label(s.group_email, text="端口:")
s.server_port.grid(row=0, column=1, padx=90, pady=10, sticky="e") #创建“SMTP服务器地址”字样的Label
s.server_port_entry = tk.Entry(s.group_email,text='', width=10) #创建SMTP服务器地址输入框
s.server_port_entry.grid(row=0, column=1, padx=10, pady=10, sticky="e")
s.sender_addr=tk.Label(s.group_email, text="发件人地址:")
s.sender_addr.grid(row=1, column=0, padx=10, pady=10, sticky="w") #创建“发件人地址”字样的Label
s.sender_addr_entry = tk.Entry(s.group_email,text='', width=50) #创建发件人地址输入框
s.sender_addr_entry.grid(row=1, column=1, padx=10, pady=10, sticky="w")
s.sender_passwd=tk.Label(s.group_email, text="密码(或授权码)")
s.sender_passwd.grid(row=2, column=0, padx=10, pady=10, sticky="w") #创建“发件人地址”字样的Label
s.sender_passwd_entry = tk.Entry(s.group_email,text='', width=50, show='*') #创建发件人地址输入框
s.sender_passwd_entry.grid(row=2, column=1, padx=10, pady=10, sticky="w")
s.receiver_addr=tk.Label(s.group_email, text="收件人(逗号隔开):")
s.receiver_addr.grid(row=3, column=0, padx=10, pady=10, sticky="w") #创建“发件人地址”字样的Label
s.receiver_addr_entry = tk.Entry(s.group_email,text='', width=50) #创建发件人地址输入框
s.receiver_addr_entry.grid(row=3, column=1, padx=10, pady=10, sticky="w")
# “发送邮件”按钮
s.send_email_button = tk.Button(s.group_email, text="发送邮件", command=s.send_email)
s.send_email_button.grid(row=0, column=2, padx=10, pady=10, sticky="e")
# 第四组 自动运行
s.group_autorun= tk.LabelFrame(s.win, text="autoRun")
s.group_autorun.grid(row=2, column=0, padx=10, pady=10, sticky="se")
#s.CheckButtonVar = tk.StringVar()
s.check_button_text = StringVar()
s.check_button_text.set('当前未自动搜索')
s.check_button_value = IntVar()
s.run_check_button = tk.Checkbutton(s.group_autorun, text="当前未自动搜索",variable = s.check_button_value, textvariable = s.check_button_text, state='normal',command=s.auto_search)
s.run_check_button.grid(row=0, column=0, padx=10, pady=10, sticky="w")# sticky="e")
s.mail_check_button_value = IntVar()
s.mail_check_button = tk.Checkbutton(s.group_autorun, text="符合需求则邮件",variable = s.mail_check_button_value,onvalue = 1, offvalue = 0, state='normal')
s.mail_check_button.grid(row=1, column=0, padx=10, pady=10, sticky="w")# sticky="e")
# s.run_background_button = tk.Button(s.win, text="后台运行", command=s.run_gackground)
# s.run_background_button.grid(row=2, column=0, padx=10, pady=10, sticky="se")
# # 日志框
s.log_data_Text = scrolledtext.ScrolledText(s.win, width=90, height=9, relief="solid")
s.log_data_Text.grid(row=3, column=0, padx=10, pady=10, sticky="w")
sys.stdout = out.StdoutRedirector(s.log_data_Text)
s.get_mail_config_info()
##去除“最小化到任务托盘”的功能,目前这功能会使得“查看桌面”的快捷键和鼠标最右下角出现问题
#s.win.bind("<Unmap>", lambda event: s.Hidden_window() if s.win.state() == 'iconic' else False) #窗口最小化判断,可以说是调用最重要的一步
#s.win.protocol('WM_DELETE_WINDOW', s.exit) #点击Tk窗口关闭时直接调用s.exit不使用默认关闭
##win32gui.ShowWindow(win, 0 )
# 单独创建一个线程用于自动运行和发送邮件
s.auto_run_thread = threading.Thread(target=s.schedule_stsk)
s.auto_run_thread.start()
# # s.auto_run_thread.join()
s.win.mainloop()
s.running_tk_win = False
s.auto_run_thread.join()
# #tk窗口
# s.root = tk.Tk()
# s.root.bind("<Unmap>", lambda event: s.Hidden_window() if s.root.state() == 'iconic' else False) #窗口最小化判断,可以说是调用最重要的一步
# s.root.protocol('WM_DELETE_WINDOW', s.exit) #点击Tk窗口关闭时直接调用s.exit不使用默认关闭
# s.root.resizable(0,0) #锁定窗口大小不能改变
# s.root.mainloop()
def exit(s, _sysTrayIcon = None):
s.win.destroy()
#print ('exit...')
def get_mail_config_info(s):
cfg.touch_config_file() #
s.server_addr_entry.insert(0, cfg.getConfig('email','host'))
s.server_port_entry.insert(0, cfg.getConfig('email','port'))
s.sender_addr_entry.insert(0, cfg.getConfig('email','sender'))
s.sender_passwd_entry.insert(0, cfg.getConfig('email','password'))
s.receiver_addr_entry.insert(0, cfg.getConfig('email','receiver'))
# mail_host = "smtp.qq.com" #SMTP服务器地址
# mail_sender = "lzm0819@qq.com" #账号
# mail_passwd = "zzqkxlaqroidjixx" #密码(或者是授权码如qq邮箱需要在设置里获取授权码)
# mail_receives="1150732137@qq.com,jimyliu@qq.com" #收件人,多个收件人地址用英文逗号隔开
def send_email(s):
path = s.file_path_entry.get()
mail_host = s.server_addr_entry.get()
mail_port = s.server_port_entry.get()
mail_sender = s.sender_addr_entry.get()
mail_passwd = s.sender_passwd_entry.get()
mail_receives = s.receiver_addr_entry.get()
if path and mail_host and mail_port and mail_sender and mail_passwd and mail_receives:
smail.send_email_with_attachment(path,mail_host,mail_port,mail_sender,mail_passwd,mail_receives)
cfg.setConfig('chipForm','path',path)
cfg.setConfig('email','host',mail_host)
cfg.setConfig('email','port',mail_port)
cfg.setConfig('email','sender',mail_sender)
cfg.setConfig('email','password',mail_passwd)
cfg.setConfig('email','receiver',mail_receives)
else:
print(out.Time(),"Warn:"+"请选择芯片表格并正确填写邮件信息!")
messagebox.showwarning("Warning","请选择芯片表格并正确填写邮件信息!")
def auto_search(s):
# 改变Checkbutton的显示值
if s.check_button_value.get() == 1:
path = s.file_path_entry.get()
if path !="":
s.run_check_button.select()
s.check_button_text.set('自动搜索中 ...... ')
# 单独创建一个线程用于自动运行和发送邮件
# s.auto_run_thread = threading.Thread(target=s.schedule_stsk)
# s.auto_run_thread.start()
# s.auto_run_thread.join()
else:
s.run_check_button.deselect()
s.check_button_text.set('当前未自动搜索')
print(out.Time(),"Warn:"+"请选择芯片表格或正确填写表格路径!")
messagebox.showwarning("Warning","请选择芯片表格或正确填写表格路径!")
else:
s.run_check_button.deselect()
s.check_button_text.set('当前未自动搜索')
# def auto_mail(s):
# if s.mail_check_button_value.get() == 1:
# s.send_email()
# else:
# None
def schedule_stsk(s):
# 当前执行一次,且以后每两小时执行一次
schedule.every(2).hours.do(s.auto_run)
#schedule.every(2).hour.until("18:00").do(s.auto_run))
#schedule.every(2).minutes.do(s.auto_run)
while s.running_tk_win :
schedule.run_pending()
time.sleep(10)
def auto_run(s):
# 如果勾选了自动运行,且当前未运行搜索,就去搜索
if (s.check_button_value.get() == 1) and (s.searching_state == False):
s.searching_state == True # searching_state相当于锁
get_msg_state,match_request_state = s.get_chips_msg()
s.searching_state == False
# 勾选了“符合条件则邮件”,且搜索信息成功,且符合需求量及价格,就发邮件
if (s.mail_check_button_value.get() == 1) and get_msg_state and match_request_state:
s.send_email()
def get_file_path(s):
file_path = filedialog.askopenfilename(title="Select A File", filetypes=(
("Microsoft Excle 文件", "*.xlsx"), ("CSV", "*.csv")))
s.file_path_entry.delete(0, 'end')
s.file_path_entry.insert(0, file_path) #写入value
#chipmsg_excle_path = file_path
if file_path != "":
#s.get_msg_button.config(state="normal")
chip_mfg_list=rwsht.read_excle_get_chips_list("input",file_path)
if chip_mfg_list:
print(out.Time(),"Info:"+"获取待搜索芯片列表成功。")
s.showAllInfo(s.dataTreeview,chip_mfg_list)
else:
print(out.Time(),"Warn:"+"芯片型号未按顺序填写或列表为空!")
else:
print(out.Time(),"Warn:"+"未选择excle表格")
return file_path
def get_chips_msg(s):
get_msg_state = False
match_request_state = False
path = s.file_path_entry.get()
if path != "":
chip_mfg_list=rwsht.read_excle_get_chips_list("input",path)
if chip_mfg_list != []:
#print(out.Time(),"获取待搜索芯片列表成功。")
print(out.Time(),"Info:"+"开始搜索...")
all_chips_list,match_request_state = getchip.serch_all_chips_from_list(chip_mfg_list)
#print(out.Time(),all_chips_list)
if all_chips_list != []:
print(out.Time(),"Info:"+"搜索芯片列表信息完成。")
write_lines=rwsht.write_chips_msg_to_excle(path,all_chips_list)
if write_lines != 0:
print(out.Time(),"Info:"+"保存芯片库存价格等信息成功。")
chip_output_list=rwsht.read_excle_get_chips_list("output",path)
s.showAllInfo(s.dataTreeview,chip_output_list)
get_msg_state = True
#messagebox.showwarning("Warning","表格信息显示不全详细信息请参考excle文档")
print(out.Time(),"Warn:"+"表格预览显示不完整详细信息请参考excle文档")
else:
print(out.Time(),"Warn:"+"保存芯片库存价格等信息失败!")
else:
print(out.Time(),"Warn:"+"搜索芯片信息失败!")
else:
#print(out.Time(),"芯片型号未按顺序填写或列表为空!")
None
else:
print(out.Time(),"Warn:"+"文件路径为空!")
messagebox.showwarning("Warning","文件路径为空!")
return get_msg_state,match_request_state
#设置窗口宽高,以及窗口在屏幕居中显示
def setWindowCenter(s,root, width, height):
screenwidth = root.winfo_screenwidth() # 获取显示屏宽度
screenheight = root.winfo_screenheight() # 获取显示屏高度
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) # 设置窗口居中参数
root.geometry(size) # 让窗口居中显示
# 显示函数
def showAllInfo(s,dataTreeview_,list):
# 先删除显示列表
if list:
x = dataTreeview_.get_children()
for item in x:
dataTreeview_.delete(item)
for item in range(len(list)):
dataTreeview_.insert("", item, text="line1", values=list[item])
if __name__ == '__main__':
Main = _Main()
Main.main()