一个到期时间提醒

查看 89|回复 9
作者:KeKeBB0609   
浏览到坛友需要一个证书到期提醒的弹窗,索性做了一个
我将在这里一步步解释代码,纯新手可以学习,高手也请指点不足


1.jpg (37.22 KB, 下载次数: 0)
下载附件
2024-4-24 16:40 上传



2.jpg (139.02 KB, 下载次数: 0)
下载附件
2024-4-24 16:40 上传



3.jpg (174.2 KB, 下载次数: 0)
下载附件
2024-4-24 16:41 上传

[Python] 纯文本查看 复制代码import tkinter as tk
from tkinter import ttk,Listbox, Button, font, filedialog, messagebox
import pandas as pd
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
import unicodedata
import re
import configparser
import os
file_path=None
refresh_time=None
remaining_days=None
def zengze(value_str):
    number = re.search(r'\d+(\.\d+)?', str(value_str))
    if number:#如果找到了匹配项,提取它的值
        extracted_number = float(number.group())
        return extracted_number
    else:
        return value_str
def pad_to_width(text, width):
    text_width = 0
    for char in text:
        char_width = unicodedata.east_asian_width(char)
        if char_width in ('F', 'W'):
            text_width += 2 #全角和宽字符占用两个字符宽度
        else:
            text_width += 1 #其他字符占用一个字符宽度
    padding_needed = width - text_width
    if padding_needed > 0:
        return text + ' ' * padding_needed
    else:
        return text #如果不需要填充,则直接返回原字符串
def read_excel_file():
    global file_path
    x=int(entry_1.get())
    file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")])#打开文件对话框以选择Excel文件
    if file_path:
        try:#使用pandas读取Excel文件
            read_excel_to_dict(file_path,remaining_days)
            xieru(file_path,x)
        except Exception as e:print(f"Error reading Excel file: {e}")#如果发生错误,打印错误信息
def auto_excel_file(file_path):
    x=int(entry_1.get())
    if file_path is not None:
        read_excel_to_dict(file_path,x)
        xieru(file_path,x)
    else:print(f'file_path:{file_path}')
def read_excel_to_dict(file_path, x):
    today = datetime.today().date()#获取当前日期
    df = pd.read_excel(file_path, engine='openpyxl')#使用pandas读取Excel文件
    dict_list = []#初始化一个空列表来存储每行的数据字典
    below_dict_list = []#初始化一个空列表来存储满足条件的数据字典
    for index, row in df.iterrows():#遍历DataFrame的每一行
        credential_name = row['证件名称']
        credential_name = pad_to_width(credential_name,20)
        valid_period_years_1 = row['证件有效期']#证件有效期以年为单位
        valid_period_years = zengze(valid_period_years_1)
        valid_period_years_1 = pad_to_width(f"   {valid_period_years_1}", 11)
        issue_Date = row['发证日期']
        date_str = "{:08d}".format(issue_Date)
        year = int(date_str[:4])
        month = int(date_str[4:6])
        day = int(date_str[6:])
        issue_Date = datetime(year, month, day).date()
        expiry_Date_1 = issue_Date + relativedelta(years=valid_period_years)
        youxiaoqi_1 = (expiry_Date_1 - today).days
        days_remaining = pad_to_width(f'     {(expiry_Date_1 - today).days}天', 15)
        expiry_Date_1 = pad_to_width(f" {expiry_Date_1.strftime('%Y-%m-%d')}", 11)
        issue_Date_1 = pad_to_width(issue_Date.strftime('%Y-%m-%d'), 11)
        Personnel_Qualification_Date = row['人员资质日期']
        date_str_1 = "{:08d}".format(Personnel_Qualification_Date)
        year_1 = int(date_str_1[:4])
        month_1 = int(date_str_1[4:6])
        day_1 = int(date_str_1[6:])
        Personnel_Qualification_Date = datetime(year_1, month_1, day_1).date()
        Validity_period_of_personnel_qualifications_1 = row['人员资质有效期']
        Validity_period_of_personnel_qualifications = zengze(Validity_period_of_personnel_qualifications_1)
        Expiration_date_of_personnel_qualification = Personnel_Qualification_Date + relativedelta(
            years=Validity_period_of_personnel_qualifications)
        youxiaoqi_2 = (Expiration_date_of_personnel_qualification - today).days
        days_remaining_1 = (Expiration_date_of_personnel_qualification - today).days
        Personnel_Qualification_Date_1 = pad_to_width(Personnel_Qualification_Date.strftime('%Y-%m-%d'), 13)
        Validity_period_of_personnel_qualifications_1 = pad_to_width(f"   {Validity_period_of_personnel_qualifications_1}",11)
        Expiration_date_of_personnel_qualification_1 = pad_to_width(
            f" {Expiration_date_of_personnel_qualification}", 14)
        days_remaining_1_1 = pad_to_width(f'   {days_remaining_1}天', 13)
        Test_report_date = row['检测报告日期']
        date_str_2 = "{:08d}".format(Test_report_date)
        year_2 = int(date_str_2[:4])
        month_2 = int(date_str_2[4:6])
        day_2 = int(date_str_2[6:])
        Test_report_date = datetime(year_2, month_2, day_2).date()
        Validity_period_of_testing_report_1 = row['检测报告有效期']
        Validity_period_of_testing_report = zengze(Validity_period_of_testing_report_1)
        Expiration_date_of_testing_report = Test_report_date + relativedelta(years=Validity_period_of_testing_report)
        youxiaoqi_3 = (Expiration_date_of_testing_report - today).days
        days_remaining_2 = (Expiration_date_of_testing_report - today).days
        Test_report_date_1 = pad_to_width(Test_report_date.strftime('%Y-%m-%d'), 10)
        Validity_period_of_testing_report_2 = pad_to_width(f"   {Validity_period_of_personnel_qualifications_1}", 13)
        Expiration_date_of_testing_report_1 = pad_to_width(f"{Expiration_date_of_testing_report.strftime('%Y-%m-%d')}",13)
        days_remaining_2_1 = pad_to_width(f'   {days_remaining_2}天', 13)
       #判断有效期是否小于指定值
        if youxiaoqi_1  0:window.after(1000,lambda: Update_time(remaining_time-1))
def on_save_config():
    global is_remember_refresh_time
    refresh_time = entry.get()
    is_remember_refresh_time = checkbox_var_1.get()#获取复选框状态
    if is_remember_refresh_time and not refresh_time:
        messagebox.showerror("错误", "请先输入刷新时间")
        return
    try:
        if is_remember_refresh_time:
            refresh_time_int = int(refresh_time)
            config = configparser.ConfigParser()#读取现有的配置文件
            config.read('settings.ini')
            if 'REFRESH_SETTINGS' not in config:#如果配置文件不存在REFRESH_SETTINGS部分,则创建它
                config['REFRESH_SETTINGS'] = {}
            config['REFRESH_SETTINGS']['refresh_time'] = str(refresh_time_int)#更新或写入刷新时间到REFRESH_SETTINGS部分  
            checkbox_1.config(text="是否记住刷新时间:是")
        else:#如果复选框未选中,则检查并删除REFRESH_SETTINGS部分(如果存在)
            checkbox_1.config(text="是否记住刷新时间:否")
            if os.path.exists('settings.ini'):
                config = configparser.ConfigParser()
                config.read('settings.ini')
                if 'REFRESH_SETTINGS' in config:#如果存在REFRESH_SETTINGS部分,则删除它
                    del config['REFRESH_SETTINGS']
                with open('settings.ini', 'w') as configfile:#将修改后的配置写回文件
                    config.write(configfile)
                messagebox.showinfo("成功", "已删除刷新时间设置")
                print('刷新时间设置已从settings.ini中删除')
        if is_remember_refresh_time:#如果复选框选中并且有有效输入,将修改后的配置写回文件
            with open('settings.ini', 'w') as configfile:
                config.write(configfile)
            messagebox.showinfo("成功", "刷新时间已保存")
            print('刷新时间已保存到settings.ini中')
            auto_up(None)
    except ValueError:
        checkbox_var_1.set(0)
        messagebox.showerror("错误", "请输入有效的刷新时间(整数)")
   
def on_text_change(P):
    try:
        int(P)#尝试将文本框内容转换为整数
        return True#验证成功,但这里不需要做任何操作,因为验证本身不会改变标签文本
    except ValueError:
        return False#验证失败,返回False阻止字符被输入
#创建一个函数来更新标签文本,当文本框失去焦点时调用
def update_label_text(event):#添加event参数
    try:
        number = int(entry.get())#获取文本框内容并转换为整数
       #更新标签文本
        if number ', update_label_text)
entry_1.bind('', update_label_1_text)
#创建按钮
read_button = tk.Button(frame_1, text="读取Excel文件", command=read_excel_file)
read_button.grid(row=1, column=2, pady=0, sticky="news")
checkbox = tk.Checkbutton(frame_1, text="是否记住文件路径:否\n(下次启动程序时不会自动读取文件)", variable=checkbox_var,command=on_checkbox_change)  
checkbox.grid(row=1, column=3, pady=0, sticky="news")
if checkbox_var :checkbox.config(text="是否记住文件路径:")
if checkbox_var_1 :
    checkbox_1.config(text="是否记住刷新时间:")
    auto_up(None)
if checkbox_var_2 :checkbox_2.config(text="是否记住剩余天数:")
auto_excel_file(file_path)
#进入消息循环
window.mainloop()

天数, 证件

KeKeBB0609
OP
  

示例表格[table][tr][td] 证件名称
KeKeBB0609
OP
  

[Python] 纯文本查看 复制代码def read_excel_file():
    global file_path
    x=int(entry_1.get())
    file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx;*.xls")])#打开文件对话框以选择Excel文件
    if file_path:
        try:#使用pandas读取Excel文件
            read_excel_to_dict(file_path,remaining_days)
            xieru(file_path,x)
        except Exception as e:print(f"Error reading Excel file: {e}")#如果发生错误,打印错误信息
定义一个read_excel_file函数用于读取Excel文件
使用global声明file_path为全局变量可以跨函数访问和修改
创建局部变量x并赋值为输入框的值
使用filedialog.askopenfilename方法打开一个文件对话框,让用户选择Excel文件。返回并将其赋值给全局变量file_path
filetypes参数指定了文件对话框中只显示Excel文件(.xlsx和.xls)。
如果file_path不为空(即用户选择了文件),则调用方法read_excel_to_dict和xieru方法并传递指定变量
KeKeBB0609
OP
  

[Python] 纯文本查看 复制代码def pad_to_width(text, width):
    text_width = 0
    for char in text:
        char_width = unicodedata.east_asian_width(char)
        if char_width in ('F', 'W'):
            text_width += 2
        else:
            text_width += 1
    padding_needed = width - text_width
    if padding_needed > 0:
        return text + ' ' * padding_needed
    else:
        return text
pad_to_width(text, width)方法接收两个变量,text接收文本,例如:‘示例:1证’,width接收整数,例如20
首先创建一个计算宽度的变量text_width并初始化为0
循环遍历接收到的字符串text,if判断遍历到的字符是否为全角或宽字符,如果是则占用两个宽度,text_width自增2,若不是则自增1。
最后判断接收到的字符串是否需要填充空格,并返回
KeKeBB0609
OP
  

[Python] 纯文本查看 复制代码def auto_excel_file(file_path):
    x=int(entry_1.get())
    if file_path is not None:
        read_excel_to_dict(file_path,x)
        xieru(file_path,x)
    else:print(f'file_path:{file_path}')
定义auto_excel_file函数接收变量auto_excel_file
x在楼上有说明
判断file_path是否不为空
实际上if是根据结果T真(true)和F假(false)来判断是否执行语句,T则执行语句,F则不执行语句或者执行else(否则)后面的语句。
而T通常为非0的值,0则为F,这里可以写成if file_path:但是这里为了防止不可预见的错误以及展示not用法故而使用此写法。
lww32   

高手高手高手高手高手高手高手高手高手
Qim626   

Python,写的很好,厉害!
心中有梦闯天下   

有没有成品分享下
KeKeBB0609
OP
  


心中有梦闯天下 发表于 2024-4-24 20:55
有没有成品分享下

明天私信给你
theonechen   

太实用了,棒棒棒
您需要登录后才可以回帖 登录 | 立即注册

返回顶部