python实现tkinter日期选择器(11种主题配色)

import tkinter as tk
import calendar
from datetime import datetime

class DatePicker:
    def __init__(self):
        # 颜色配置
        # 暗夜领域
        self.colors = {
            'primary': '#007BFF',
            'secondary': '#0056b3',
            'background': '#222222',
            'text': '#EEEEEE',
            'highlight': '#333333',
            'weekend': '#FF4500',
            'hover': '#444444'
        }
        # 绿野仙踪
        self.colors = {
            'primary': '#4CAF50',
            'secondary': '#388E3C',
            'background': '#F1F8E9',
            'text': '#212121',
            'highlight': '#C8E6C9',
            'weekend': '#FFAB91',
            'hover': '#E8F5E9'
        }
        # 晨日辉光
        self.colors = {
            'primary': '#FFA500',
            'secondary': '#FF8C00',
            'background': '#FFF8E1',
            'text': '#212121',
            'highlight': '#FFE0B2',
            'weekend': '#FF6347',
            'hover': '#FFCC80'
        }
        # 静谧之湖
        self.colors = {
            'primary': '#40E0D0',
            'secondary': '#00BFFF',
            'background': '#E0FFFF',
            'text': '#333333',
            'highlight': '#AFEEEE',
            'weekend': '#87CEFA',
            'hover': '#B0E0E6'
        }
        # 黄金麦穗
        self.colors = {
            'primary': '#FFD700',
            'secondary': '#D4AF37',
            'background': '#F8F0E3',
            'text': '#333333',
            'highlight': '#FFE87C',
            'weekend': '#FFBC52',
            'hover': '#FFF3BF'
        }
        # 青花玉瓷
        self.colors = {
            'primary': '#00BFFF',
            'secondary': '#009ACD',
            'background': '#E1F5FE',
            'text': '#333333',
            'highlight': '#87CEFA',
            'weekend': '#FFA07A',
            'hover': '#B0E0E6'
        }
        # 青柠气泡
        self.colors = {
            'primary': '#32CD32',
            'secondary': '#008000',
            'background': '#F0FFF0',
            'text': '#333333',
            'highlight': '#98FB98',
            'weekend': '#BBBB00',
            'hover': '#CCFFCC'
        }
        # 大吉大利
        self.colors = {
            'primary': '#FF0000',
            'secondary': '#FFD700',
            'background': '#8B0000',
            'text': '#FFFFFF',
            'highlight': '#FFBC52',
            'weekend': '#FFE87C',
            'hover': '#FFF3BF'
        }
        # 灰色幽默
        self.colors = {
            'primary': '#696969',
            'secondary': '#A9A9A9',
            'background': '#D3D3D3',
            'text': '#2F4F4F',
            'highlight': '#778899',
            'weekend': '#FF6347',
            'hover': '#E0E0E0'
        }
        # 沉稳大气
        self.colors = {
            'primary': '#333333',
            'secondary': '#666666',
            'background': '#F5F5F2',
            'text': '#222222',
            'highlight': '#999999',
            'weekend': '#D4AF37',
            'hover': '#E0E0E0'
        }
        # 科技时尚
        self.colors = {
            'primary': '#2E86C1',
            'secondary': '#5DADE2',
            'background': '#FFFFFF',
            'text': '#2C3E50',
            'highlight': '#E8F6F3',
            'weekend': '#E74C3C',
            'hover': '#EBF5FB'
        }

        self.root = tk.Tk()
        self.root.withdraw()  # 隐藏主窗口
        self.top = tk.Toplevel(self.root)
        self.top.title("日期选择")
        self.top.geometry("320x400+500+200")
        self.top.resizable(False, False)
        self.top.configure(bg=self.colors["background"])
        self.top.option_add('*Font', 'SegoeUI')
        self.top.attributes('-topmost', True)
        self.top.overrideredirect(True)

        # 拖拽相关变量
        self.dragging = False
        self.offset_x = 0
        self.offset_y = 0


        self.current_year = datetime.now().year
        self.current_month = datetime.now().month
        self.today = datetime.now().day
        self.selected_date = None
        self.selected_button = None

        # 中文月份名称
        self.chinese_months = ['', '一月', '二月', '三月', '四月', '五月', '六月',
                               '七月', '八月', '九月', '十月', '十一月', '十二月']

        self.create_widgets()
        self.top.grab_set()  # 设置为模态窗口

        # 绑定拖拽事件
        self.top.bind("<ButtonPress-1>", self.on_drag_start)
        self.top.bind("<B1-Motion>", self.on_drag_motion)
        self.top.bind("<ButtonRelease-1>", self.on_drag_end)

    def create_widgets(self):
        self.create_header()
        self.create_weekdays()
        self.create_calendar_grid()
        self.create_confirm_button()

    def create_header(self):
        header_frame = tk.Frame(self.top, bg=self.colors['background'], pady=15)
        header_frame.pack(fill=tk.X)

        # 上月按钮
        self.btn_prev = tk.Button(
            header_frame,
            text="⟨",
            command=self.prev_month,
            font=('Segoe UI', 14, 'bold'),
            fg=self.colors['primary'],
            bg=self.colors['background'],
            relief='flat',
            activebackground=self.colors['hover']
        )
        self.btn_prev.pack(side=tk.LEFT, padx=10)

        # 月份显示
        self.month_label = tk.Label(
            header_frame,
            font=('Segoe UI', 16, 'bold'),
            fg=self.colors['text'],
            bg=self.colors['background']
        )
        self.month_label.pack(side=tk.LEFT, expand=True)

        # 下月按钮
        self.btn_next = tk.Button(
            header_frame,
            text="⟩",
            command=self.next_month,
            font=('Segoe UI', 14, 'bold'),
            fg=self.colors['primary'],
            bg=self.colors['background'],
            relief='flat',
            activebackground=self.colors['hover']
        )
        self.btn_next.pack(side=tk.RIGHT, padx=10)

    def create_weekdays(self):
        weekdays_frame = tk.Frame(self.top, bg=self.colors['background'], pady=10)
        weekdays_frame.pack()

        weekdays = ["一", "二", "三", "四", "五", "六", "日"]
        for i, day in enumerate(weekdays):
            color = self.colors['weekend'] if i >= 5 else self.colors['text']
            lbl = tk.Label(
                weekdays_frame,
                text=day,
                font=('Segoe UI', 10),
                fg=color,
                bg=self.colors['background'],
                width=4,
                padx=2
            )
            lbl.grid(row=0, column=i, sticky='ew', padx=1)

        for col in range(7):
            weekdays_frame.columnconfigure(col, weight=1, uniform='weekday')

    def create_calendar_grid(self):
        self.calendar_frame = tk.Frame(self.top, bg=self.colors['background'], padx=5, pady=5)
        self.calendar_frame.pack()
        for col in range(7):
            self.calendar_frame.columnconfigure(col, weight=1, uniform='day')
        self.update_calendar()

    def update_calendar(self):
        for widget in self.calendar_frame.winfo_children():
            widget.destroy()

        self.selected_button = None
        month_days = calendar.monthcalendar(self.current_year, self.current_month)
        month_name = self.chinese_months[self.current_month]
        self.month_label.config(text=f"{self.current_year} {month_name}")

        for week_num, week in enumerate(month_days):
            for day_num in range(7):
                day = week[day_num] if day_num < len(week) else 0

                if day == 0:
                    tk.Label(self.calendar_frame, text="", bg=self.colors['background'], width=4) \
                        .grid(row=week_num + 1, column=day_num, padx=2, pady=2)
                    continue

                btn = tk.Button(
                    self.calendar_frame,
                    text=str(day),
                    width=4,
                    relief='flat',
                    font=('Segoe UI', 10),
                    fg=self.colors['text'],
                    bg=self.colors['background'],
                    activebackground=self.colors['hover'],
                    padx=2
                )

                def create_command(day=day, btn=btn):
                    return lambda: self.select_date(day, btn)

                btn.config(command=create_command())
                btn.bind("<Enter>", lambda e, b=btn: b.config(bg=self.colors['hover']))
                btn.bind("<Leave>", lambda e, b=btn: b.config(
                    bg=self.colors['primary'] if b == self.selected_button else self.colors['background']))

                if (day == self.today and
                        self.current_month == datetime.now().month and
                        self.current_year == datetime.now().year):
                    btn.config(fg=self.colors['primary'], relief='groove')

                if day_num >= 5:
                    btn.config(fg=self.colors['weekend'])

                btn.grid(row=week_num + 1, column=day_num, sticky='ew', padx=2, pady=2)

    def select_date(self, day, btn):
        if self.selected_button:
            self.selected_button.config(bg=self.colors['background'], fg=self.colors['text'])
            if (self.selected_button['text'] == str(self.today) and
                    self.current_month == datetime.now().month):
                self.selected_button.config(fg=self.colors['primary'])

        self.selected_date = datetime(self.current_year, self.current_month, day)
        self.selected_button = btn
        self.selected_button.config(bg=self.colors['primary'], fg='white')

    def prev_month(self):
        self.current_month -= 1
        if self.current_month == 0:
            self.current_month = 12
            self.current_year -= 1
        self.update_calendar()

    def next_month(self):
        self.current_month += 1
        if self.current_month == 13:
            self.current_month = 1
            self.current_year += 1
        self.update_calendar()

    def create_confirm_button(self):
        button_frame = tk.Frame(self.top, bg=self.colors['background'], pady=15)
        button_frame.pack(fill=tk.X)

        confirm_btn = tk.Button(
            button_frame,
            text="确 定",
            command=self.confirm_selection,
            font=('Segoe UI', 12, 'bold'),
            fg='white',
            bg=self.colors['primary'],
            relief='flat',
            activebackground=self.colors['secondary'],
            padx=30,
            pady=8
        )
        confirm_btn.pack()
        confirm_btn.bind("<Enter>", lambda e: confirm_btn.config(bg=self.colors['secondary']))
        confirm_btn.bind("<Leave>", lambda e: confirm_btn.config(bg=self.colors['primary']))

    def confirm_selection(self):
        if not self.selected_date:
            self.selected_date = datetime.now()
        self.top.destroy()
        self.root.quit()

    def run(self):
        self.root.mainloop()
        return self.selected_date.strftime("%Y-%m-%d")

    # 拖拽相关方法
    def on_drag_start(self, event):
        self.dragging = True
        self.offset_x = event.x
        self.offset_y = event.y

    def on_drag_motion(self, event):
        if self.dragging:
            x = self.top.winfo_x() - self.offset_x + event.x
            y = self.top.winfo_y() - self.offset_y + event.y
            # 限制窗口在屏幕内
            screen_width = self.top.winfo_screenwidth()
            screen_height = self.top.winfo_screenheight()
            x = max(0, min(x, screen_width - self.top.winfo_width()))
            y = max(0, min(y, screen_height - self.top.winfo_height()))
            self.top.geometry(f'+{x}+{y}')

    def on_drag_end(self, event):
        self.dragging = False


def get_selected_date():
    picker = DatePicker()
    return picker.run()


if __name__ == "__main__":
    selected_date = get_selected_date()
    print("选择的日期是:", selected_date)
import tkinter as tk
import calendar
from datetime import datetime

class DatePicker:
    def __init__(self):
        # 颜色配置
        # 暗夜领域
        self.colors = {
            'primary': '#007BFF',
            'secondary': '#0056b3',
            'background': '#222222',
            'text': '#EEEEEE',
            'highlight': '#333333',
            'weekend': '#FF4500',
            'hover': '#444444'
        }
        # 绿野仙踪
        self.colors = {
            'primary': '#4CAF50',
            'secondary': '#388E3C',
            'background': '#F1F8E9',
            'text': '#212121',
            'highlight': '#C8E6C9',
            'weekend': '#FFAB91',
            'hover': '#E8F5E9'
        }
        # 晨日辉光
        self.colors = {
            'primary': '#FFA500',
            'secondary': '#FF8C00',
            'background': '#FFF8E1',
            'text': '#212121',
            'highlight': '#FFE0B2',
            'weekend': '#FF6347',
            'hover': '#FFCC80'
        }
        # 静谧之湖
        self.colors = {
            'primary': '#40E0D0',
            'secondary': '#00BFFF',
            'background': '#E0FFFF',
            'text': '#333333',
            'highlight': '#AFEEEE',
            'weekend': '#87CEFA',
            'hover': '#B0E0E6'
        }
        # 黄金麦穗
        self.colors = {
            'primary': '#FFD700',
            'secondary': '#D4AF37',
            'background': '#F8F0E3',
            'text': '#333333',
            'highlight': '#FFE87C',
            'weekend': '#FFBC52',
            'hover': '#FFF3BF'
        }
        # 青花玉瓷
        self.colors = {
            'primary': '#00BFFF',
            'secondary': '#009ACD',
            'background': '#E1F5FE',
            'text': '#333333',
            'highlight': '#87CEFA',
            'weekend': '#FFA07A',
            'hover': '#B0E0E6'
        }
        # 青柠气泡
        self.colors = {
            'primary': '#32CD32',
            'secondary': '#008000',
            'background': '#F0FFF0',
            'text': '#333333',
            'highlight': '#98FB98',
            'weekend': '#BBBB00',
            'hover': '#CCFFCC'
        }
        # 大吉大利
        self.colors = {
            'primary': '#FF0000',
            'secondary': '#FFD700',
            'background': '#8B0000',
            'text': '#FFFFFF',
            'highlight': '#FFBC52',
            'weekend': '#FFE87C',
            'hover': '#FFF3BF'
        }
        # 灰色幽默
        self.colors = {
            'primary': '#696969',
            'secondary': '#A9A9A9',
            'background': '#D3D3D3',
            'text': '#2F4F4F',
            'highlight': '#778899',
            'weekend': '#FF6347',
            'hover': '#E0E0E0'
        }
        # 沉稳大气
        self.colors = {
            'primary': '#333333',
            'secondary': '#666666',
            'background': '#F5F5F2',
            'text': '#222222',
            'highlight': '#999999',
            'weekend': '#D4AF37',
            'hover': '#E0E0E0'
        }
        # 科技时尚
        self.colors = {
            'primary': '#2E86C1',
            'secondary': '#5DADE2',
            'background': '#FFFFFF',
            'text': '#2C3E50',
            'highlight': '#E8F6F3',
            'weekend': '#E74C3C',
            'hover': '#EBF5FB'
        }

        self.root = tk.Tk()
        self.root.withdraw()  # 隐藏主窗口
        self.top = tk.Toplevel(self.root)
        self.top.title("日期选择")
        self.top.geometry("320x400+500+200")
        self.top.resizable(False, False)
        self.top.configure(bg=self.colors["background"])
        self.top.option_add('*Font', 'SegoeUI')
        self.top.attributes('-topmost', True)
        self.top.overrideredirect(True)

        # 拖拽相关变量
        self.dragging = False
        self.offset_x = 0
        self.offset_y = 0


        self.current_year = datetime.now().year
        self.current_month = datetime.now().month
        self.today = datetime.now().day
        self.selected_date = None
        self.selected_button = None

        # 中文月份名称
        self.chinese_months = ['', '一月', '二月', '三月', '四月', '五月', '六月',
                               '七月', '八月', '九月', '十月', '十一月', '十二月']

        self.create_widgets()
        self.top.grab_set()  # 设置为模态窗口

        # 绑定拖拽事件
        self.top.bind("<ButtonPress-1>", self.on_drag_start)
        self.top.bind("<B1-Motion>", self.on_drag_motion)
        self.top.bind("<ButtonRelease-1>", self.on_drag_end)

    def create_widgets(self):
        self.create_header()
        self.create_weekdays()
        self.create_calendar_grid()
        self.create_confirm_button()

    def create_header(self):
        header_frame = tk.Frame(self.top, bg=self.colors['background'], pady=15)
        header_frame.pack(fill=tk.X)

        # 上月按钮
        self.btn_prev = tk.Button(
            header_frame,
            text="⟨",
            command=self.prev_month,
            font=('Segoe UI', 14, 'bold'),
            fg=self.colors['primary'],
            bg=self.colors['background'],
            relief='flat',
            activebackground=self.colors['hover']
        )
        self.btn_prev.pack(side=tk.LEFT, padx=10)

        # 月份显示
        self.month_label = tk.Label(
            header_frame,
            font=('Segoe UI', 16, 'bold'),
            fg=self.colors['text'],
            bg=self.colors['background']
        )
        self.month_label.pack(side=tk.LEFT, expand=True)

        # 下月按钮
        self.btn_next = tk.Button(
            header_frame,
            text="⟩",
            command=self.next_month,
            font=('Segoe UI', 14, 'bold'),
            fg=self.colors['primary'],
            bg=self.colors['background'],
            relief='flat',
            activebackground=self.colors['hover']
        )
        self.btn_next.pack(side=tk.RIGHT, padx=10)

    def create_weekdays(self):
        weekdays_frame = tk.Frame(self.top, bg=self.colors['background'], pady=10)
        weekdays_frame.pack()

        weekdays = ["一", "二", "三", "四", "五", "六", "日"]
        for i, day in enumerate(weekdays):
            color = self.colors['weekend'] if i >= 5 else self.colors['text']
            lbl = tk.Label(
                weekdays_frame,
                text=day,
                font=('Segoe UI', 10),
                fg=color,
                bg=self.colors['background'],
                width=4,
                padx=2
            )
            lbl.grid(row=0, column=i, sticky='ew', padx=1)

        for col in range(7):
            weekdays_frame.columnconfigure(col, weight=1, uniform='weekday')

    def create_calendar_grid(self):
        self.calendar_frame = tk.Frame(self.top, bg=self.colors['background'], padx=5, pady=5)
        self.calendar_frame.pack()
        for col in range(7):
            self.calendar_frame.columnconfigure(col, weight=1, uniform='day')
        self.update_calendar()

    def update_calendar(self):
        for widget in self.calendar_frame.winfo_children():
            widget.destroy()

        self.selected_button = None
        month_days = calendar.monthcalendar(self.current_year, self.current_month)
        month_name = self.chinese_months[self.current_month]
        self.month_label.config(text=f"{self.current_year} {month_name}")

        for week_num, week in enumerate(month_days):
            for day_num in range(7):
                day = week[day_num] if day_num < len(week) else 0

                if day == 0:
                    tk.Label(self.calendar_frame, text="", bg=self.colors['background'], width=4) \
                        .grid(row=week_num + 1, column=day_num, padx=2, pady=2)
                    continue

                btn = tk.Button(
                    self.calendar_frame,
                    text=str(day),
                    width=4,
                    relief='flat',
                    font=('Segoe UI', 10),
                    fg=self.colors['text'],
                    bg=self.colors['background'],
                    activebackground=self.colors['hover'],
                    padx=2
                )

                def create_command(day=day, btn=btn):
                    return lambda: self.select_date(day, btn)

                btn.config(command=create_command())
                btn.bind("<Enter>", lambda e, b=btn: b.config(bg=self.colors['hover']))
                btn.bind("<Leave>", lambda e, b=btn: b.config(
                    bg=self.colors['primary'] if b == self.selected_button else self.colors['background']))

                if (day == self.today and
                        self.current_month == datetime.now().month and
                        self.current_year == datetime.now().year):
                    btn.config(fg=self.colors['primary'], relief='groove')

                if day_num >= 5:
                    btn.config(fg=self.colors['weekend'])

                btn.grid(row=week_num + 1, column=day_num, sticky='ew', padx=2, pady=2)

    def select_date(self, day, btn):
        if self.selected_button:
            self.selected_button.config(bg=self.colors['background'], fg=self.colors['text'])
            if (self.selected_button['text'] == str(self.today) and
                    self.current_month == datetime.now().month):
                self.selected_button.config(fg=self.colors['primary'])

        self.selected_date = datetime(self.current_year, self.current_month, day)
        self.selected_button = btn
        self.selected_button.config(bg=self.colors['primary'], fg='white')

    def prev_month(self):
        self.current_month -= 1
        if self.current_month == 0:
            self.current_month = 12
            self.current_year -= 1
        self.update_calendar()

    def next_month(self):
        self.current_month += 1
        if self.current_month == 13:
            self.current_month = 1
            self.current_year += 1
        self.update_calendar()

    def create_confirm_button(self):
        button_frame = tk.Frame(self.top, bg=self.colors['background'], pady=15)
        button_frame.pack(fill=tk.X)

        confirm_btn = tk.Button(
            button_frame,
            text="确 定",
            command=self.confirm_selection,
            font=('Segoe UI', 12, 'bold'),
            fg='white',
            bg=self.colors['primary'],
            relief='flat',
            activebackground=self.colors['secondary'],
            padx=30,
            pady=8
        )
        confirm_btn.pack()
        confirm_btn.bind("<Enter>", lambda e: confirm_btn.config(bg=self.colors['secondary']))
        confirm_btn.bind("<Leave>", lambda e: confirm_btn.config(bg=self.colors['primary']))

    def confirm_selection(self):
        if not self.selected_date:
            self.selected_date = datetime.now()
        self.top.destroy()
        self.root.quit()

    def run(self):
        self.root.mainloop()
        return self.selected_date.strftime("%Y-%m-%d")

    # 拖拽相关方法
    def on_drag_start(self, event):
        self.dragging = True
        self.offset_x = event.x
        self.offset_y = event.y

    def on_drag_motion(self, event):
        if self.dragging:
            x = self.top.winfo_x() - self.offset_x + event.x
            y = self.top.winfo_y() - self.offset_y + event.y
            # 限制窗口在屏幕内
            screen_width = self.top.winfo_screenwidth()
            screen_height = self.top.winfo_screenheight()
            x = max(0, min(x, screen_width - self.top.winfo_width()))
            y = max(0, min(y, screen_height - self.top.winfo_height()))
            self.top.geometry(f'+{x}+{y}')

    def on_drag_end(self, event):
        self.dragging = False


def get_selected_date():
    picker = DatePicker()
    return picker.run()


if __name__ == "__main__":
    selected_date = get_selected_date()
    print("选择的日期是:", selected_date)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值