【教程】使用ChatGPT制作基于Tkinter的桌面时钟

目录

描述

代码

效果

说明

下载

描述

        给ChatGPT的描述内容:

        python在桌面上显示动态的文字,不要显示窗口边框。窗口背景和标签背景都是透明的,但标签内的文字是有颜色。使用tkinter库实现,并以class的形式书写,方便用户对内容进行扩展开发。

        窗口默认出现在屏幕的中间位置。窗口中的标签需要包含两项内容。其中一项用于实时显示当前的日期和时间,精确到毫秒。另一项从txt文件中读取显示,若没有txt文件则显示“None”。

        在未锁定状态下,鼠标可以拖动窗口。在锁定状态下,窗口无法通过鼠标的拖动而移动。在窗口中添加一个“锁定”按钮,当鼠标移动到窗口上方时,显示“锁定”按钮,鼠标移走后,隐藏“锁定”按钮。通过“锁定”按钮,窗口进入锁定状态。在锁定状态下,当鼠标移动到窗口上方时,显示一个“解除锁定”的按钮,鼠标移走后,隐藏该“解除锁定”按钮。通过点击“解除锁定”按钮,进入未锁定状态。锁定和未锁定状态是互相切换的。

        给窗口添加一个鼠标右键的功能,在右键菜单中,可以点击“退出”,从而退出应用。

        窗口中的内容居中显示。

        添加 右键窗口显示“改变颜色”子菜单,点击后,弹出颜色选择框,通过选择不同的颜色,可以改变窗口的背景颜色。

        添加 右键窗口显示“置顶”子菜单,点击后,可以使当前窗口一直保持在最前面。在置顶状态下,再右键窗口,改为显示“取消置顶”。

        添加右键“修改日期”子菜单,点击后,弹出开始日期选择框和结束日期选择框,选择完毕后,更新到self.start_date和self.end_date,并立即调用update_note_label函数。

        添加 右键窗口显示“修改note”子菜单,点击后,弹出内容输入框,输入框默认显示“小锋学长生活大爆炸”。点击确认后,输入框的内容更新到self.text_label。只需要给出修改的关键代码。

        启动时从http://xfxuezhang.cn/web/share/version获取desktop_clock.txt文件,根据内容与当前版本是否一致,若不一致则弹窗提示有更新

 

代码

给出的代码,并经过微调:

import tkinter as tk
import datetime
import math
import locale
import os
from tkinter.colorchooser import askcolor
import webbrowser
import tkinter.messagebox as messagebox
import tkinter.ttk as ttk
import tkcalendar
import babel.numbers
import requests
import tkinter.simpledialog



# Set the locale to use UTF-8 encoding
locale.setlocale(locale.LC_ALL, 'en_US.utf8')
VERSION = '20230329'

class TransparentWindow(tk.Tk):
    def __init__(self, text_file=None):
        super().__init__()
        self.attributes('-alpha', 1) # 设置窗口透明度
        # self.attributes('-topmost', True) # 窗口置顶
        # self.attributes('-transparentcolor', '#000000')
        self.overrideredirect(True) # 去掉窗口边框
        self.locked = False # 初始化锁定状态
        self.mouse_x = 0
        self.mouse_y = 0
        self.config(bg='#000000', highlightthickness=0, bd=0)
        self.start_date = '2023/2/20'
        self.end_date = '2023/7/9'
        
        # 获取屏幕尺寸和窗口尺寸,使窗口居中
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        window_width = 400
        window_height = 100
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        self.geometry('{}x{}+{}+{}'.format(window_width, window_height, x, y))

        # 添加日期时间标签
        self.datetime_label = tk.Label(self, text='', font=('Arial', 20), fg='#FFFFFF', bg='#000000')
        self.datetime_label.place(relx=0.5, y=20, anchor='center')

        # 提示标签
        self.note_label = tk.Label(self, text='123', font=('Arial', 14), fg='#FFFFFF', bg='#000000')
        self.note_label.place(relx=0.5, y=50, anchor='center')

        # 文本标签
        self.text_label = tk.Label(self, text='', font=('Arial', 14), fg='#FFFFFF', bg='#000000')
        self.text_label.place(relx=0.5, y=80, anchor='center')

        # 添加锁定按钮
        self.lock_button = tk.Button(self, text='锁定', font=('Arial', 10), command=self.toggle_lock)
        self.toggle_lock_button(True)
        self.toggle_lock_button(False)

        # 添加解锁按钮
        self.unlock_button = tk.Button(self, text='解除锁定', font=('Arial', 10), command=self.toggle_lock)
        self.toggle_unlock_button(True)
        self.toggle_unlock_button(False)

        # 定时更新日期时间标签
        self.update_datetime()
        # 定时更新text标签
        self.update_text_label()
        # 定时更新note标签
        self.update_note_label()

        # 绑定鼠标事件
        self.bind('<Button-1>', self.on_left_button_down)
        self.bind('<ButtonRelease-1>', self.on_left_button_up)
        self.bind('<B1-Motion>', self.on_mouse_drag)
        self.bind('<Enter>', self.on_mouse_enter)
        self.bind('<Leave>', self.on_mouse_leave)

        # 创建右键菜单
        self.menu = tk.Menu(self, tearoff=0)
        self.menu.add_command(label="退出", command=self.quit)
        # 添加“置顶”子菜单
        self.menu.add_command(label="置顶", command=self.topmost_on)
        # 添加“改变颜色”子菜单
        self.menu.add_command(label="选择颜色", command=self.choose_color)
        # 添加“修改日期”子菜单
        self.menu.add_command(label="修改日期", command=self.modify_date)
        # 添加“修改note”子菜单
        self.menu.add_command(label='修改note', command=self.edit_note)
        # 添加“关于”子菜单
        self.menu.add_command(label="关于", command=self.about_me)
        self.bind("<Button-3>", self.show_menu)

        self.check_version()
    
    
    def check_version(self):
        url = 'http://xfxuezhang.cn/web/share/version/desktop_clock.txt'
        try:
            resp = requests.get(url, timeout=2).text.strip()
            if resp != VERSION:
                if messagebox.askyesno('更新提示', '发现新版本,是否前往蓝奏云下载?密码:c9o1'):
                    webbrowser.open('https://xfxuezhang.lanzouo.com/b09ubrasb')
        except:
            pass

    def about_me(self):
        # webbrowser.open_new_tab('http://www.xfxuezhang.cn')
        messagebox.showinfo("关于", "暂时没什么内容")

    # 选择日期
    def modify_date(self):
        top = tk.Toplevel(self)
        # 获取屏幕尺寸和窗口尺寸,使窗口居中
        screen_width = top.winfo_screenwidth()
        screen_height = top.winfo_screenheight()
        window_width = 175
        window_height = 100
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        top.geometry('{}x{}+{}+{}'.format(window_width, window_height, x, y))
        top.title('选择日期')
        tk.Label(top, text='开始日期:').grid(row=0, column=0)
        start_date = tkcalendar.DateEntry(top, width=12, background='darkblue', foreground='white', date_pattern='yyyy/mm/dd', date=self.start_date, justify='center')
        start_date.grid(row=0, column=1)
        tk.Label(top, text='结束日期:').grid(row=1, column=0)
        end_date = tkcalendar.DateEntry(top, width=12, background='darkblue', foreground='white', date_pattern='yyyy/mm/dd', date=self.end_date, justify='center')
        end_date.grid(row=1, column=1)
    
        def update_dates():
            self.start_date = start_date.get_date().strftime('%Y/%m/%d')
            self.end_date = end_date.get_date().strftime('%Y/%m/%d')
            self.update_note_label()
            top.destroy()
        
        button = tk.Button(top, text="确定", command=update_dates)
        button.grid(row=2, column=0, columnspan=2, pady=10)

    # 窗口置顶
    def topmost_on(self):
        if self.attributes('-topmost'):
            self.attributes('-topmost', False)
            self.menu.entryconfig(1, label='置顶')
        else:
            self.attributes('-topmost', True)
            self.menu.entryconfig(1, label='取消置顶')

    # 改变背景色
    def choose_color(self):
        color = askcolor()[1]
        if color:
            self.config(bg=color)
            self.datetime_label.config(bg=color)
            self.note_label.config(bg=color)
            self.text_label.config(bg=color)

    # 锁定
    def toggle_lock_button(self, show=True):
        if show:
            self.lock_button.place(relx=1, rely=0.85, anchor='e')
        else:
            self.lock_button.place_forget()
    
    # 解除锁定
    def toggle_unlock_button(self, show=True):
        if show:
            self.unlock_button.place(relx=1, rely=0.85, anchor='e')
        else:
            self.unlock_button.place_forget()
    # 锁定和解除锁定的切换
    def toggle_lock(self):
        if self.locked:
            self.locked = False
            self.toggle_lock_button(True)
            self.toggle_unlock_button(False)
        else:
            self.locked = True
            self.toggle_lock_button(False)
            self.toggle_unlock_button(True)

    # 显示右键菜单
    def show_menu(self, event):
        self.menu.post(event.x_root, event.y_root)

    # 更新日期时间
    def update_datetime(self):
        now = datetime.datetime.now().strftime('%Y-%m-%d     \u270d     %H:%M:%S.%f')[:-4]
        msg = f'{now}'
        self.datetime_label.configure(text=msg)
        self.after(10, self.update_datetime)

    # 更新txt文档内容
    def update_text_label(self):
        now = ''
        if os.path.exists('config.txt'):
            now = open('config.txt', 'r', encoding='utf8').read().strip()
        now = now or '小锋学长生活大爆炸'
        self.text_label.configure(text=now)
        # self.after(1000, self.update_text_label)

    def edit_note(self):
        """打开文本输入框并更新内容"""
        # 创建文本输入框并显示默认内容
        note = tkinter.simpledialog.askstring('修改note', '请输入新的note', initialvalue=self.text_label['text'], parent=self)
        # 如果用户点击确认,则更新文本标签的内容
        if note:
            self.text_label['text'] = note

    # 更新周次
    def update_note_label(self):
        # 指定日期,格式为 年-月-日
        start_y, start_m, start_d = list(map(int, self.start_date.strip().split('/')))
        end_y, end_m, end_d = list(map(int, self.end_date.strip().split('/')))
        specified_start_date = datetime.date(start_y, start_m, start_d)
        specified_end_date = datetime.date(end_y, end_m, end_d)
        today = datetime.date.today()
        # 计算距离指定日期过了多少周
        start_delta = today - specified_start_date
        num_of_weeks = math.ceil(start_delta.days / 7)
        # 计算距离指定日期剩余多少周
        end_delta = specified_end_date - today
        remain_weeks = math.ceil(end_delta.days / 7)

        msg = f'当前第{num_of_weeks}周, 剩余{remain_weeks}周({end_delta.days}天)'
        self.note_label.configure(text=msg)
        self.after(1000*60, self.update_note_label)



    # 实现窗口拖动
    def on_left_button_down(self, event):
        self.mouse_x = event.x
        self.mouse_y = event.y

    # 实现窗口拖动
    def on_left_button_up(self, event):
        self.mouse_x = 0
        self.mouse_y = 0

    # 实现窗口拖动
    def on_mouse_drag(self, event):
        if not self.locked:
            x = self.winfo_x() + event.x - self.mouse_x
            y = self.winfo_y() + event.y - self.mouse_y
            self.geometry('+{}+{}'.format(x, y))

    def on_mouse_leave(self, event):
        self.lock_button.place_forget()
        self.unlock_button.place_forget()

    def on_mouse_enter(self, event):
        if not self.locked:
            self.toggle_lock_button(True)
            self.toggle_unlock_button(False)
        else:
            self.toggle_lock_button(False)
            self.toggle_unlock_button(True)


if __name__ == '__main__':
    app = TransparentWindow(text_file='text.txt')
    app.mainloop()


效果

界面上鼠标点击右键可以选择“退出”:


鼠标移动到界面,会显示“锁定”和“解除锁定”按钮:

说明

        关于背景颜色、日期等等内容,大家可以修改相应的代码。

下载

https://xfxuezhang.lanzouo.com/b09ubrasb
密码:c9o1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/5105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GPS时间序列分析---剔除跳跃点,拟合时间序列

通常利用GPS时间序列进行数据分析时&#xff0c;会遇到大地震的发生&#xff0c;这个时候会导致GPS的观测结果出现很大的跳跃值&#xff0c;这对后续的数据处理和分析带来了困难。这里分享一个最近了解的&#xff0c;可以用于处理这一问题的工具包---TSAnalyzer。下面主要介绍该…

Adobe:当创意工作遇上生成式AI

放眼全球IT行业&#xff0c;当前最炙手可热的领域是什么&#xff1f;答案显然只有一个&#xff1a;因为ChatGPT而火爆全球的生成式AI&#xff08;Artificial Intelligence Generated Content&#xff0c;简称AIGC&#xff09;&#xff0c;又称人工智能生成内容。那么当创意设计…

再学一下Feign的原理

简介 Feign是Spring Cloud Netflix组件中的一个轻量级Restful的HTTP服务客户端&#xff0c;它简化了服务间调用的方式。 Feign是一个声明式的web service客户端.它的出现使开发web service客户端变得更简单.使用Feign只需要创建一个接口加上对应的注解, 比如FeignClient注解。…

Go分布式爬虫学习笔记(十四)

文章目录14_context为什么需要Context?级联退出Context 的使用方法。context.ValuecontextContext 最佳实践Context 底层原理14_context Never start a goroutine without knowing how it will stop。 如果你不知道协程如何退出&#xff0c;就不要使用它。 为什么需要Context?…

家政服务系统APP小程序需具备哪些功能?

由于工作忙碌或者是懒人经济作祟&#xff0c;现代人对于家政服务的需求直线上升。而且互联网技术深入生活的方方面面&#xff0c;让上门家政服务系统开发成为很多线下家政公司转型互联网的方式&#xff0c;那么开发一款家政服务系统APP小程序需具备哪些功能呢&#xff1f; …

逻辑回归 算法推导与基于Python的实现详解

文章目录1 逻辑回归概述2 逻辑回归公式推导与求解2.1 公式推导2.2公式求解3 基于Python的实现3.1可接收参数3.2 完整代码示例1 逻辑回归概述 逻辑回归&#xff08;Logistic Regression&#xff09;是一种用于分类问题的统计学习方法。它基于线性回归的原理&#xff0c;通过将线…

【软考——系统架构师】架构、系分、软设的区别和联系

&#x1f50e;这里是【软考——系统架构师】&#xff0c;关注我考试轻松过线 &#x1f44d;如果对你有帮助&#xff0c;给博主一个免费的点赞以示鼓励 欢迎各位&#x1f50e;点赞&#x1f44d;评论收藏⭐️ 文章目录&#x1f440;三科相同点&#x1f440;三科不同点--上午题&am…

CISAW-CISDR灾难备份与恢复专业级认证

证书样板&#xff1a; 认证机构 中国网络安全审查技术与认证中心&#xff08;英文缩写为&#xff1a;CCRC,原为中国信息安全认证中心&#xff09;于 2006 年由中央机构编制委员会办公室批准成立&#xff0c;为国家市场监督管理总局直属事业单位。依据《网络安全法》 《网络安…

Java每日一练(20230401)

目录 1. 合并K个升序链表 &#x1f31f;&#x1f31f;&#x1f31f; 2. 最长有效括号 &#x1f31f;&#x1f31f;&#x1f31f; 3. 分割回文串 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 …

Linux系统一键安装最新内核并开启 BBR 脚本

本脚本适用环境 系统支持&#xff1a;CentOS 6&#xff0c;Debian 8&#xff0c;Ubuntu 16 虚拟技术&#xff1a;OpenVZ 以外的&#xff0c;比如 KVM、Xen、VMware 内存要求&#xff1a;≥128M 更新日期&#xff1a;2022 年 5 月 11 日 关于本脚本 1、本脚本已在 蓝易云 上…

后端Springboot框架搭建APi接口开发(第二章)

上一章我讲述了如何使用Mybatis操作数据库。这一章我讲述如何利用Sptring框架搭建API接口 第一节&#xff1a;封装SqlSessionFactory工具类 在API操作数据库大量调用SqlSessionFactory&#xff0c;因此应将SqlSessionFactory封装成工具类供方法随时调用 在文件结构中的util文…

前端直接生成GIF动态图实践

前言去年在博客中发了两篇关于GIF动态生成的博客&#xff0c;GIF图像动态生成-JAVA后台生成和基于FFmpeg的Java视频Mp4转GIF初探&#xff0c;在这两篇博客中都是采用JAVA语言在后台进行转换。使用JAVA的同学经过自己的改造和开发也可以应用在项目上。前段时间有朋友私下问&…

MySQL主从复制、读写分离(MayCat2)实现数据同步

文章目录1.MySQL主从复制原理。2.实现MySQL主从复制&#xff08;一主两从&#xff09;。3.基于MySQL一主两从配置&#xff0c;完成MySQL读写分离配置。&#xff08;MyCat2&#xff09;1.MySQL主从复制原理。 MySQL主从复制是一个异步的复制过程&#xff0c;底层是基于Mysql数据…

设计模式之门面模式(C++)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 一、门面模式是什么&#xff1f; 门面模式是一种结构型的软件设计模式&#xff0c;也叫外观模式&#xff0c;它提供了统一的接口去…

程序员的天花板到底有多高?

程序员是很多人眼里的职业天花板&#xff0c;毕竟薪资水平、发展前景摆在那里&#xff0c;而且&#xff0c;一个又会debug又会修电脑&#xff08;划掉&#xff09;&#xff0c;还会费心为你制造浪漫的程序员&#xff0c;有谁不喜欢呢&#xff1f; 但现实中很多程序员都焦虑担忧…

从0使用TCP手撸http服务器六

html模板设计&#xff1a; 上篇我们说到通过路由去返回不同的html页面&#xff0c;如果每一个页面都是一个数组的话&#xff0c;那么我们可能需要很多数组&#xff0c;里面很多内容都是一样的&#xff0c;这样子会浪费我们单片机很多flash&#xff0c;我们需要把共同的部分固定…

神经网络之反向传播算法(加入Nesterov动量的误差反向传播算法)

文章目录1、Nesterov动量2、结合Nesterov动量的误差反向传播算法3、算法实现3.1 训练过程3.2 测试过程4、参考源码及数据集1、Nesterov动量 在动量法提出不久之后&#xff0c;Nesterov动量也随之被提了出来&#xff0c;此方法属于动量法的进一步发展&#xff0c;与动量法不同的…

基于windows11配置深度学习环境包含WSL2配置ubuntu20.04

基于windows11配置深度学习环境包含WSL2配置ubuntu20.04目录平台WSL2 系统准备(Windows Subsystem of Linux)安装WSL2基于WSL2中的Ubuntu安装CUDA和cudnnCUDA 安装目录 平台 系统 : windows11 专业版 CPU Intel I7 8750hq 显卡&#xff1a;Nvidia GTX1060移动端 显卡驱动版本…

安装Windows11提示这台电脑不符合安装此版本的Windows所需的最低系统要求

现在很多用户都会选择用U盘来安装系统&#xff0c;最新有用户在使用U盘安装Win11系统的时候&#xff0c;结果安装到第一步就提示这台电脑无法运行Windows11&#xff0c;这台电脑不符合安装此版本的Windows所需的最低系统要求。下面小编就来教大家解决此问题的方法。 问题解析&a…

BIO/NIO/AIO/IO多路复用简介

bio、nio、aio、io多路复用、reactor模式io&#xff0c;在将IO的时候&#xff0c;是不是都遇到过这些概念&#xff0c;也有种傻傻分不清&#xff1f;甚至别人在大谈特谈的时候&#xff0c;一会nio&#xff0c;一会io多路复用&#xff0c;一会又搞到reactor模式上去了&#xff1…