最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Python開發(fā)一個(gè)日歷記賬小工具

 更新時(shí)間:2025年08月26日 09:59:25   作者:小莊-Python辦公  
這篇文章主要為大家詳細(xì)介紹了一個(gè)基于Python和tkinter開發(fā)的簡潔實(shí)用的日歷記賬工具,可以幫助您輕松管理日常收支記錄,感興趣的小伙伴可以了解一下

前言

一個(gè)基于Python和tkinter開發(fā)的簡潔實(shí)用的日歷記賬工具,幫助您輕松管理日常收支記錄。

功能特點(diǎn)

日歷界面

  • 直觀的月歷顯示
  • 不同顏色標(biāo)識收支狀態(tài):
    • 綠色:當(dāng)日收入大于支出
    • 紅色:當(dāng)日支出大于收入
    • 黃色:當(dāng)日收支平衡
    • 灰色:無記錄

記賬功能

  • 添加收入記錄
  • 添加支出記錄
  • 為每筆記錄添加詳細(xì)描述
  • 查看和刪除當(dāng)日記錄

統(tǒng)計(jì)功能

  • 實(shí)時(shí)顯示總收入、總支出和凈收入
  • 底部統(tǒng)計(jì)欄一目了然

導(dǎo)出功能

  • 支持選擇日期范圍導(dǎo)出
  • 導(dǎo)出為CSV格式,便于進(jìn)一步分析
  • 包含完整的記錄信息和時(shí)間戳

安裝和運(yùn)行

系統(tǒng)要求

Python 3.6 或更高版本

tkinter(通常隨Python一起安裝)

運(yùn)行步驟

確保已安裝Python

下載項(xiàng)目文件

在項(xiàng)目目錄中運(yùn)行:

python calendar_accounting.py

使用說明

基本操作

選擇日期:擊日歷上的任意日期

添加記錄:

  • 輸入金額(必須為正數(shù))
  • 輸入描述信息
  • 點(diǎn)擊"添加收入"或"添加支出"

查看記錄:選擇日期后,當(dāng)日記錄會顯示在右側(cè)列表中

刪除記錄:選中列表中的記錄,點(diǎn)擊"刪除選中記錄"

導(dǎo)航操作

使用"?"和"?"按鈕切換月份

日歷會自動更新顯示當(dāng)前月份的收支狀態(tài)

導(dǎo)出數(shù)據(jù)

  • 設(shè)置導(dǎo)出的開始和結(jié)束日期
  • 點(diǎn)擊"導(dǎo)出CSV"按鈕
  • 選擇保存位置和文件名
  • 數(shù)據(jù)將以CSV格式保存,可用Excel等軟件打開

數(shù)據(jù)存儲

所有記賬數(shù)據(jù)保存在accounting_data.json文件中

數(shù)據(jù)格式為JSON,便于備份和遷移

程序啟動時(shí)自動加載歷史數(shù)據(jù)

完整代碼

import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import calendar
import json
import os
from datetime import datetime, date
from collections import defaultdict

class CalendarAccountingApp:
    def __init__(self, root):
        self.root = root
        self.root.title("?? 日歷記賬小工具")
        self.root.geometry("1200x800")
        self.root.resizable(True, True)
        
        # 設(shè)置現(xiàn)代化主題色彩
        self.colors = {
            'primary': '#2E86AB',      # 主色調(diào) - 藍(lán)色
            'secondary': '#A23B72',    # 次要色 - 紫紅色
            'success': '#F18F01',      # 成功色 - 橙色
            'danger': '#C73E1D',       # 危險(xiǎn)色 - 紅色
            'light': '#F5F5F5',        # 淺色背景
            'dark': '#2C3E50',         # 深色文字
            'income': '#27AE60',       # 收入色 - 綠色
            'expense': '#E74C3C',      # 支出色 - 紅色
            'balance': '#F39C12',      # 平衡色 - 橙色
            'card_bg': '#FFFFFF',      # 卡片背景
            'border': '#E0E0E0'        # 邊框色
        }
        
        # 設(shè)置根窗口樣式
        self.root.configure(bg=self.colors['light'])
        
        # 配置ttk樣式
        self.setup_styles()
        
        # 數(shù)據(jù)存儲文件
        self.data_file = "accounting_data.json"
        self.load_data()
        
        # 當(dāng)前顯示的年月
        self.current_year = datetime.now().year
        self.current_month = datetime.now().month
        
        # 選中的日期
        self.selected_date = None
        
        self.create_widgets()
        self.update_calendar()
        self.update_statistics()
    
    def setup_styles(self):
        """設(shè)置現(xiàn)代化樣式主題"""
        style = ttk.Style()
        
        # 配置LabelFrame樣式
        style.configure('Card.TLabelframe', 
                       background=self.colors['card_bg'],
                       borderwidth=1,
                       relief='solid')
        style.configure('Card.TLabelframe.Label',
                       background=self.colors['card_bg'],
                       foreground=self.colors['primary'],
                       font=('Microsoft YaHei UI', 11, 'bold'))
        
        # 配置按鈕樣式
        style.configure('Primary.TButton',
                       background=self.colors['primary'],
                       foreground='white',
                       font=('Microsoft YaHei UI', 9, 'bold'),
                       padding=(10, 5))
        
        style.configure('Success.TButton',
                       background=self.colors['income'],
                       foreground='white',
                       font=('Microsoft YaHei UI', 9, 'bold'),
                       padding=(10, 5))
        
        style.configure('Danger.TButton',
                       background=self.colors['expense'],
                       foreground='white',
                       font=('Microsoft YaHei UI', 9, 'bold'),
                       padding=(10, 5))
        
        # 配置Entry樣式
        style.configure('Modern.TEntry',
                       fieldbackground='white',
                       borderwidth=1,
                       relief='solid',
                       padding=(8, 5))
        
        # 配置Treeview樣式
        style.configure('Modern.Treeview',
                       background='white',
                       foreground=self.colors['dark'],
                       rowheight=25,
                       fieldbackground='white')
        style.configure('Modern.Treeview.Heading',
                       background=self.colors['primary'],
                       foreground='white',
                       font=('Microsoft YaHei UI', 9, 'bold'))
        
        # 配置Label樣式
        style.configure('Title.TLabel',
                       background=self.colors['card_bg'],
                       foreground=self.colors['dark'],
                       font=('Microsoft YaHei UI', 10, 'bold'))
        
        style.configure('Stats.TLabel',
                       background=self.colors['card_bg'],
                       foreground=self.colors['primary'],
                       font=('Microsoft YaHei UI', 12, 'bold'))
    
    def load_data(self):
        """加載記賬數(shù)據(jù)"""
        if os.path.exists(self.data_file):
            try:
                with open(self.data_file, 'r', encoding='utf-8') as f:
                    self.data = json.load(f)
            except:
                self.data = {}
        else:
            self.data = {}
    
    def save_data(self):
        """保存記賬數(shù)據(jù)"""
        with open(self.data_file, 'w', encoding='utf-8') as f:
            json.dump(self.data, f, ensure_ascii=False, indent=2)
    
    def create_widgets(self):
        """創(chuàng)建界面組件"""
        # 主框架
        main_frame = tk.Frame(self.root, bg=self.colors['light'], padx=20, pady=20)
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置網(wǎng)格權(quán)重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(1, weight=1)
        
        # 左側(cè)日歷區(qū)域
        calendar_frame = ttk.LabelFrame(main_frame, text="?? 日歷視圖", padding="15", style='Card.TLabelframe')
        calendar_frame.grid(row=0, column=0, rowspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 15))
        
        # 年月選擇
        date_frame = tk.Frame(calendar_frame, bg=self.colors['card_bg'])
        date_frame.grid(row=0, column=0, columnspan=7, pady=(0, 15))
        
        prev_btn = tk.Button(date_frame, text="?", command=self.prev_month,
                           bg=self.colors['primary'], fg='white', font=('Microsoft YaHei UI', 12, 'bold'),
                           relief='flat', padx=15, pady=5, cursor='hand2')
        prev_btn.grid(row=0, column=0, padx=(0, 10))
        
        self.month_label = tk.Label(date_frame, text="", font=('Microsoft YaHei UI', 14, 'bold'),
                                  bg=self.colors['card_bg'], fg=self.colors['dark'])
        self.month_label.grid(row=0, column=1, padx=20)
        
        next_btn = tk.Button(date_frame, text="?", command=self.next_month,
                           bg=self.colors['primary'], fg='white', font=('Microsoft YaHei UI', 12, 'bold'),
                           relief='flat', padx=15, pady=5, cursor='hand2')
        next_btn.grid(row=0, column=2, padx=(10, 0))
        
        # 日歷網(wǎng)格
        self.calendar_buttons = {}
        
        # 星期標(biāo)題
        weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
        for i, day in enumerate(weekdays):
            label = tk.Label(calendar_frame, text=day, font=('Microsoft YaHei UI', 10, 'bold'),
                           bg=self.colors['secondary'], fg='white', pady=8)
            label.grid(row=1, column=i, padx=2, pady=2, sticky=(tk.W, tk.E))
        
        # 日期按鈕
        for week in range(6):
            for day in range(7):
                btn = tk.Button(calendar_frame, text="", width=6, height=2,
                              font=('Microsoft YaHei UI', 10, 'bold'),
                              relief='flat', cursor='hand2',
                              command=lambda w=week, d=day: self.select_date(w, d))
                btn.grid(row=week+2, column=day, padx=2, pady=2, sticky=(tk.W, tk.E))
                self.calendar_buttons[(week, day)] = btn
        
        # 右側(cè)操作區(qū)域
        right_frame = tk.Frame(main_frame, bg=self.colors['light'])
        right_frame.grid(row=0, column=1, sticky=(tk.W, tk.E, tk.N, tk.S))
        right_frame.columnconfigure(0, weight=1)
        
        # 記賬操作區(qū)
        account_frame = ttk.LabelFrame(right_frame, text="?? 記賬操作", padding="15", style='Card.TLabelframe')
        account_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        account_frame.columnconfigure(1, weight=1)
        
        # 選中日期顯示
        ttk.Label(account_frame, text="?? 選中日期:", style='Title.TLabel').grid(row=0, column=0, sticky=tk.W)
        self.selected_date_label = tk.Label(account_frame, text="請選擇日期", 
                                          fg=self.colors['primary'], bg=self.colors['card_bg'],
                                          font=('Microsoft YaHei UI', 10, 'bold'))
        self.selected_date_label.grid(row=0, column=1, sticky=tk.W, padx=(10, 0))
        
        # 金額輸入
        ttk.Label(account_frame, text="?? 金額:", style='Title.TLabel').grid(row=1, column=0, sticky=tk.W, pady=(15, 0))
        self.amount_var = tk.StringVar()
        amount_entry = ttk.Entry(account_frame, textvariable=self.amount_var, width=20, style='Modern.TEntry')
        amount_entry.grid(row=1, column=1, sticky=tk.W, padx=(10, 0), pady=(15, 0))
        
        # 描述輸入
        ttk.Label(account_frame, text="?? 描述:", style='Title.TLabel').grid(row=2, column=0, sticky=tk.W, pady=(15, 0))
        self.desc_var = tk.StringVar()
        desc_entry = ttk.Entry(account_frame, textvariable=self.desc_var, width=35, style='Modern.TEntry')
        desc_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), padx=(10, 0), pady=(15, 0))
        
        # 按鈕
        btn_frame = tk.Frame(account_frame, bg=self.colors['card_bg'])
        btn_frame.grid(row=3, column=0, columnspan=2, pady=(20, 0))
        
        income_btn = tk.Button(btn_frame, text="?? 添加收入", command=lambda: self.add_record('income'),
                             bg=self.colors['income'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'),
                             relief='flat', padx=20, pady=8, cursor='hand2')
        income_btn.grid(row=0, column=0, padx=(0, 15))
        
        expense_btn = tk.Button(btn_frame, text="?? 添加支出", command=lambda: self.add_record('expense'),
                              bg=self.colors['expense'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'),
                              relief='flat', padx=20, pady=8, cursor='hand2')
        expense_btn.grid(row=0, column=1)
        
        # 當(dāng)日記錄顯示區(qū)
        records_frame = ttk.LabelFrame(right_frame, text="?? 當(dāng)日記錄", padding="15", style='Card.TLabelframe')
        records_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 15))
        records_frame.columnconfigure(0, weight=1)
        records_frame.rowconfigure(0, weight=1)
        
        # 記錄列表
        self.records_tree = ttk.Treeview(records_frame, columns=('type', 'amount', 'desc'), 
                                       show='headings', height=8, style='Modern.Treeview')
        self.records_tree.heading('type', text='?? 類型')
        self.records_tree.heading('amount', text='?? 金額')
        self.records_tree.heading('desc', text='?? 描述')
        self.records_tree.column('type', width=80)
        self.records_tree.column('amount', width=100)
        self.records_tree.column('desc', width=250)
        
        scrollbar = ttk.Scrollbar(records_frame, orient=tk.VERTICAL, command=self.records_tree.yview)
        self.records_tree.configure(yscrollcommand=scrollbar.set)
        
        self.records_tree.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
        
        # 刪除按鈕
        delete_btn = tk.Button(records_frame, text="??? 刪除選中記錄", command=self.delete_record,
                             bg=self.colors['danger'], fg='white', font=('Microsoft YaHei UI', 9, 'bold'),
                             relief='flat', padx=15, pady=5, cursor='hand2')
        delete_btn.grid(row=1, column=0, pady=(15, 0))
        
        # 底部統(tǒng)計(jì)和導(dǎo)出區(qū)
        bottom_frame = tk.Frame(main_frame, bg=self.colors['light'])
        bottom_frame.grid(row=1, column=1, sticky=(tk.W, tk.E))
        bottom_frame.columnconfigure(0, weight=1)
        
        # 統(tǒng)計(jì)信息
        stats_frame = ttk.LabelFrame(bottom_frame, text="?? 統(tǒng)計(jì)信息", padding="15", style='Card.TLabelframe')
        stats_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        
        self.stats_label = tk.Label(stats_frame, text="總收入: ¥0.00 | 總支出: ¥0.00 | 凈收入: ¥0.00", 
                                  font=('Microsoft YaHei UI', 12, 'bold'),
                                  bg=self.colors['card_bg'], fg=self.colors['primary'])
        self.stats_label.grid(row=0, column=0)
        
        # 導(dǎo)出功能
        export_frame = ttk.LabelFrame(bottom_frame, text="?? 導(dǎo)出功能", padding="15", style='Card.TLabelframe')
        export_frame.grid(row=1, column=0, sticky=(tk.W, tk.E))
        
        ttk.Label(export_frame, text="?? 導(dǎo)出范圍:", style='Title.TLabel').grid(row=0, column=0, sticky=tk.W)
        
        date_range_frame = tk.Frame(export_frame, bg=self.colors['card_bg'])
        date_range_frame.grid(row=0, column=1, sticky=tk.W, padx=(15, 0))
        
        self.start_date_var = tk.StringVar(value=f"{self.current_year}-{self.current_month:02d}-01")
        ttk.Entry(date_range_frame, textvariable=self.start_date_var, width=12, style='Modern.TEntry').grid(row=0, column=0)
        tk.Label(date_range_frame, text=" 至 ", bg=self.colors['card_bg'], fg=self.colors['dark'],
               font=('Microsoft YaHei UI', 10)).grid(row=0, column=1, padx=10)
        
        last_day = calendar.monthrange(self.current_year, self.current_month)[1]
        self.end_date_var = tk.StringVar(value=f"{self.current_year}-{self.current_month:02d}-{last_day:02d}")
        ttk.Entry(date_range_frame, textvariable=self.end_date_var, width=12, style='Modern.TEntry').grid(row=0, column=2)
        
        export_btn = tk.Button(export_frame, text="?? 導(dǎo)出CSV", command=self.export_csv,
                             bg=self.colors['success'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'),
                             relief='flat', padx=20, pady=5, cursor='hand2')
        export_btn.grid(row=0, column=2, padx=(25, 0))
    
    def prev_month(self):
        """上一個(gè)月"""
        if self.current_month == 1:
            self.current_month = 12
            self.current_year -= 1
        else:
            self.current_month -= 1
        self.update_calendar()
        self.update_date_range()
    
    def next_month(self):
        """下一個(gè)月"""
        if self.current_month == 12:
            self.current_month = 1
            self.current_year += 1
        else:
            self.current_month += 1
        self.update_calendar()
        self.update_date_range()
    
    def update_date_range(self):
        """更新導(dǎo)出日期范圍"""
        self.start_date_var.set(f"{self.current_year}-{self.current_month:02d}-01")
        last_day = calendar.monthrange(self.current_year, self.current_month)[1]
        self.end_date_var.set(f"{self.current_year}-{self.current_month:02d}-{last_day:02d}")
    
    def update_calendar(self):
        """更新日歷顯示"""
        # 更新月份標(biāo)簽
        self.month_label.config(text=f"?? {self.current_year}年{self.current_month}月")
        
        # 獲取月歷
        cal = calendar.monthcalendar(self.current_year, self.current_month)
        
        # 清空所有按鈕
        for btn in self.calendar_buttons.values():
            btn.config(text="", state=tk.DISABLED, bg="SystemButtonFace")
        
        # 填充日期
        for week_num, week in enumerate(cal):
            for day_num, day in enumerate(week):
                if day == 0:
                    continue
                
                btn = self.calendar_buttons[(week_num, day_num)]
                btn.config(text=str(day), state=tk.NORMAL)
                
                # 檢查是否有記錄
                date_str = f"{self.current_year}-{self.current_month:02d}-{day:02d}"
                if date_str in self.data:
                    # 計(jì)算當(dāng)日收支
                    daily_income = sum(record['amount'] for record in self.data[date_str] if record['type'] == 'income')
                    daily_expense = sum(record['amount'] for record in self.data[date_str] if record['type'] == 'expense')
                    
                    if daily_income > daily_expense:
                        btn.config(bg=self.colors['income'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'))  # 收入大于支出
                    elif daily_expense > daily_income:
                        btn.config(bg=self.colors['expense'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'))  # 支出大于收入
                    else:
                        btn.config(bg=self.colors['balance'], fg='white', font=('Microsoft YaHei UI', 10, 'bold'))  # 收支平衡
                else:
                    btn.config(bg='white', fg=self.colors['dark'], font=('Microsoft YaHei UI', 10), 
                             relief='solid', bd=1, activebackground=self.colors['light'])
    
    def select_date(self, week, day):
        """選擇日期"""
        btn = self.calendar_buttons[(week, day)]
        if btn['text'] == "":
            return
        
        day_num = int(btn['text'])
        self.selected_date = f"{self.current_year}-{self.current_month:02d}-{day_num:02d}"
        self.selected_date_label.config(text=self.selected_date)
        
        # 更新當(dāng)日記錄顯示
        self.update_daily_records()
    
    def update_daily_records(self):
        """更新當(dāng)日記錄顯示"""
        # 清空列表
        for item in self.records_tree.get_children():
            self.records_tree.delete(item)
        
        if not self.selected_date or self.selected_date not in self.data:
            return
        
        # 添加記錄
        for record in self.data[self.selected_date]:
            type_text = "收入" if record['type'] == 'income' else "支出"
            amount_text = f"¥{record['amount']:.2f}"
            self.records_tree.insert('', tk.END, values=(type_text, amount_text, record['description']))
    
    def add_record(self, record_type):
        """添加記錄"""
        if not self.selected_date:
            messagebox.showwarning("警告", "請先選擇日期")
            return
        
        try:
            amount = float(self.amount_var.get())
            if amount <= 0:
                raise ValueError()
        except ValueError:
            messagebox.showerror("錯(cuò)誤", "請輸入有效的金額")
            return
        
        description = self.desc_var.get().strip()
        if not description:
            messagebox.showwarning("警告", "請輸入描述")
            return
        
        # 添加記錄
        if self.selected_date not in self.data:
            self.data[self.selected_date] = []
        
        record = {
            'type': record_type,
            'amount': amount,
            'description': description,
            'timestamp': datetime.now().isoformat()
        }
        
        self.data[self.selected_date].append(record)
        self.save_data()
        
        # 清空輸入
        self.amount_var.set("")
        self.desc_var.set("")
        
        # 更新顯示
        self.update_calendar()
        self.update_daily_records()
        self.update_statistics()
        
        messagebox.showinfo("成功", f"已添加{('收入' if record_type == 'income' else '支出')}記錄")
    
    def delete_record(self):
        """刪除選中的記錄"""
        selection = self.records_tree.selection()
        if not selection:
            messagebox.showwarning("警告", "請選擇要?jiǎng)h除的記錄")
            return
        
        if messagebox.askyesno("確認(rèn)", "確定要?jiǎng)h除選中的記錄嗎?"):
            # 獲取選中項(xiàng)的索引
            item = selection[0]
            index = self.records_tree.index(item)
            
            # 刪除數(shù)據(jù)
            if self.selected_date in self.data and index < len(self.data[self.selected_date]):
                del self.data[self.selected_date][index]
                
                # 如果該日期沒有記錄了,刪除日期鍵
                if not self.data[self.selected_date]:
                    del self.data[self.selected_date]
                
                self.save_data()
                
                # 更新顯示
                self.update_calendar()
                self.update_daily_records()
                self.update_statistics()
                
                messagebox.showinfo("成功", "記錄已刪除")
    
    def update_statistics(self):
        """更新統(tǒng)計(jì)信息"""
        total_income = 0
        total_expense = 0
        
        for date_records in self.data.values():
            for record in date_records:
                if record['type'] == 'income':
                    total_income += record['amount']
                else:
                    total_expense += record['amount']
        
        net_income = total_income - total_expense
        
        # 根據(jù)凈收入設(shè)置顏色
        if net_income > 0:
            color = self.colors['income']
            icon = "??"
        elif net_income < 0:
            color = self.colors['expense']
            icon = "??"
        else:
            color = self.colors['balance']
            icon = "??"
        
        stats_text = f"?? 總收入: ¥{total_income:.2f} | ?? 總支出: ¥{total_expense:.2f} | {icon} 凈收入: ¥{net_income:.2f}"
        self.stats_label.config(text=stats_text, fg=color)
    
    def export_csv(self):
        """導(dǎo)出CSV文件"""
        try:
            start_date = datetime.strptime(self.start_date_var.get(), "%Y-%m-%d").date()
            end_date = datetime.strptime(self.end_date_var.get(), "%Y-%m-%d").date()
        except ValueError:
            messagebox.showerror("錯(cuò)誤", "日期格式不正確,請使用YYYY-MM-DD格式")
            return
        
        if start_date > end_date:
            messagebox.showerror("錯(cuò)誤", "開始日期不能大于結(jié)束日期")
            return
        
        # 選擇保存文件
        filename = filedialog.asksaveasfilename(
            defaultextension=".csv",
            filetypes=[("CSV文件", "*.csv"), ("所有文件", "*.*")],
            title="保存導(dǎo)出文件"
        )
        
        if not filename:
            return
        
        try:
            import csv
            with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile:
                writer = csv.writer(csvfile)
                writer.writerow(['日期', '類型', '金額', '描述', '時(shí)間戳'])
                
                # 按日期排序?qū)С?
                current_date = start_date
                while current_date <= end_date:
                    date_str = current_date.strftime("%Y-%m-%d")
                    if date_str in self.data:
                        for record in self.data[date_str]:
                            type_text = "收入" if record['type'] == 'income' else "支出"
                            writer.writerow([
                                date_str,
                                type_text,
                                f"{record['amount']:.2f}",
                                record['description'],
                                record.get('timestamp', '')
                            ])
                    
                    # 下一天
                    from datetime import timedelta
                    current_date += timedelta(days=1)
            
            messagebox.showinfo("成功", f"數(shù)據(jù)已導(dǎo)出到: {filename}")
        
        except Exception as e:
            messagebox.showerror("錯(cuò)誤", f"導(dǎo)出失敗: {str(e)}")

def main():
    root = tk.Tk()
    app = CalendarAccountingApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

效果圖

文件結(jié)構(gòu)

日歷記賬小工具/
├── calendar_accounting.py    # 主程序文件
└── accounting_data.json     # 數(shù)據(jù)文件(運(yùn)行后自動生成)

技術(shù)特點(diǎn)

使用Python標(biāo)準(zhǔn)庫開發(fā),無需安裝額外依賴

基于tkinter構(gòu)建GUI界面,跨平臺兼容

JSON格式數(shù)據(jù)存儲,輕量且易于維護(hù)

響應(yīng)式界面設(shè)計(jì),支持窗口大小調(diào)整

注意事項(xiàng)

請確保輸入的金額為有效數(shù)字

建議定期備份accounting_data.json文件

導(dǎo)出的CSV文件使用UTF-8編碼,確保中文正常顯示

到此這篇關(guān)于基于Python開發(fā)一個(gè)日歷記賬小工具的文章就介紹到這了,更多相關(guān)Python日歷記賬內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 十個(gè)Python經(jīng)典小游戲的代碼合集

    十個(gè)Python經(jīng)典小游戲的代碼合集

    這篇文章主要為大家分享十個(gè)Python經(jīng)典的小游戲代碼,非常適合Python初學(xué)者練手。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-05-05
  • Python爬取股票信息,并可視化數(shù)據(jù)的示例

    Python爬取股票信息,并可視化數(shù)據(jù)的示例

    這篇文章主要介紹了Python爬取股票信息,并可視化數(shù)據(jù)的示例,幫助大家更好的理解和使用python爬蟲,感興趣的朋友可以了解下
    2020-09-09
  • python中from module import * 的一個(gè)坑

    python中from module import * 的一個(gè)坑

    from module import *把module中的成員全部導(dǎo)到了當(dāng)前的global namespace,訪問起來就比較方便了。當(dāng)然,python style一般不建議這么做,因?yàn)榭赡芤餹ame conflict。
    2014-07-07
  • 一文教你如何創(chuàng)建Python虛擬環(huán)境venv

    一文教你如何創(chuàng)建Python虛擬環(huán)境venv

    創(chuàng)建?Python?虛擬環(huán)境是一個(gè)很好的實(shí)踐,可以幫助我們管理項(xiàng)目的依賴項(xiàng),避免不同項(xiàng)目之間的沖突,下面就跟隨小編一起學(xué)習(xí)一下如何創(chuàng)建Python虛擬環(huán)境venv吧
    2024-12-12
  • Python實(shí)現(xiàn)多級目錄壓縮與解壓文件的方法

    Python實(shí)現(xiàn)多級目錄壓縮與解壓文件的方法

    這篇文章主要介紹了Python實(shí)現(xiàn)多級目錄壓縮與解壓文件的方法,涉及Python針對文件路徑的遍歷、判斷以及文件壓縮、解壓縮等相關(guān)操作技巧,需要的朋友可以參考下
    2018-09-09
  • Python中的__new__與__init__魔術(shù)方法理解筆記

    Python中的__new__與__init__魔術(shù)方法理解筆記

    這篇文章主要介紹了Python中的__new__與__init__魔術(shù)方法理解筆記,需要的朋友可以參考下
    2014-11-11
  • Python使用Scrapy下載圖片的兩種方式

    Python使用Scrapy下載圖片的兩種方式

    Scrapy是一個(gè)適用爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)性數(shù)據(jù)的應(yīng)用程序框架,它可以通過定制化的修改來滿足不同的爬蟲需求,本文給大家介紹了Python使用Scrapy下載圖片的兩種方式,需要的朋友可以參考下
    2025-08-08
  • Python使用schedule庫實(shí)現(xiàn)任務(wù)定時(shí)自動化

    Python使用schedule庫實(shí)現(xiàn)任務(wù)定時(shí)自動化

    在Python的自動化工具庫中,schedule是一個(gè)簡潔又強(qiáng)大的存在,無論是定時(shí)備份數(shù)據(jù)、周期性抓取網(wǎng)頁,還是定期發(fā)送提醒郵件,schedule庫都能讓我們的代碼按計(jì)劃精準(zhǔn)執(zhí)行,今天我們就深入了解schedule庫的使用,需要的朋友可以參考下
    2026-04-04
  • Python組合pyenv和venv進(jìn)行項(xiàng)目環(huán)境隔離配置指南

    Python組合pyenv和venv進(jìn)行項(xiàng)目環(huán)境隔離配置指南

    這篇文章將詳細(xì)講解如何通過 pyenv(管理 Python 解釋器版本)和 venv(Python 內(nèi)置虛擬環(huán)境)的組合,實(shí)現(xiàn)不同項(xiàng)目的 Python 版本隔離、依賴版本隔離,徹底解決一個(gè)環(huán)境跑所有項(xiàng)目導(dǎo)致的版本沖突的問題,希望對大家有所幫助
    2026-02-02
  • 使用Python的matplotlib庫繪制柱狀圖

    使用Python的matplotlib庫繪制柱狀圖

    這篇文章主要介紹了使用Python的matplotlib庫繪制柱狀圖,Matplotlib是Python中最常用的可視化工具之一,可以非常方便地創(chuàng)建海量類型地2D圖表和一些基本的3D圖表,可根據(jù)數(shù)據(jù)集自行定義x,y軸,繪制圖形,需要的朋友可以參考下
    2023-07-07

最新評論

安龙县| 旌德县| 灯塔市| 比如县| 阳新县| 前郭尔| 塔河县| 商河县| 斗六市| 永定县| 武胜县| 仁布县| 屏山县| 南漳县| 兴业县| 米泉市| 金华市| 太原市| 开远市| 宁乡县| 阳江市| 桐乡市| 嘉义县| 大关县| 桂阳县| 鲜城| 金溪县| 前郭尔| 永修县| 岐山县| 封丘县| 科尔| 宝坻区| 许昌县| 青铜峡市| 习水县| 金门县| 鹤岗市| 濉溪县| 广东省| 乐安县|