315 lines
16 KiB
Python
315 lines
16 KiB
Python
#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()
|