目錄
描述
代碼
效果
說明
下載
開源鏈接:GitHub - 1061700625/Tkinter_Desktop_Clock: 基于Tkinter的桌面時(shí)鐘小工具
描述
????????給ChatGPT的描述內(nèi)容:
????????python在桌面上顯示動(dòng)態(tài)的文字,不要顯示窗口邊框。窗口背景和標(biāo)簽背景都是透明的,但標(biāo)簽內(nèi)的文字是有顏色。使用tkinter庫實(shí)現(xiàn),并以class的形式書寫,方便用戶對(duì)內(nèi)容進(jìn)行擴(kuò)展開發(fā)。
????????窗口默認(rèn)出現(xiàn)在屏幕的中間位置。窗口中的標(biāo)簽需要包含兩項(xiàng)內(nèi)容。其中一項(xiàng)用于實(shí)時(shí)顯示當(dāng)前的日期和時(shí)間,精確到毫秒。另一項(xiàng)從txt文件中讀取顯示,若沒有txt文件則顯示“None”。
????????在未鎖定狀態(tài)下,鼠標(biāo)可以拖動(dòng)窗口。在鎖定狀態(tài)下,窗口無法通過鼠標(biāo)的拖動(dòng)而移動(dòng)。在窗口中添加一個(gè)“鎖定”按鈕,當(dāng)鼠標(biāo)移動(dòng)到窗口上方時(shí),顯示“鎖定”按鈕,鼠標(biāo)移走后,隱藏“鎖定”按鈕。通過“鎖定”按鈕,窗口進(jìn)入鎖定狀態(tài)。在鎖定狀態(tài)下,當(dāng)鼠標(biāo)移動(dòng)到窗口上方時(shí),顯示一個(gè)“解除鎖定”的按鈕,鼠標(biāo)移走后,隱藏該“解除鎖定”按鈕。通過點(diǎn)擊“解除鎖定”按鈕,進(jìn)入未鎖定狀態(tài)。鎖定和未鎖定狀態(tài)是互相切換的。
????????給窗口添加一個(gè)鼠標(biāo)右鍵的功能,在右鍵菜單中,可以點(diǎn)擊“退出”,從而退出應(yīng)用。
????????窗口中的內(nèi)容居中顯示。
????????添加 右鍵窗口顯示“改變顏色”子菜單,點(diǎn)擊后,彈出顏色選擇框,通過選擇不同的顏色,可以改變窗口的背景顏色。
????????添加 右鍵窗口顯示“置頂”子菜單,點(diǎn)擊后,可以使當(dāng)前窗口一直保持在最前面。在置頂狀態(tài)下,再右鍵窗口,改為顯示“取消置頂”。
????????添加右鍵“修改日期”子菜單,點(diǎn)擊后,彈出開始日期選擇框和結(jié)束日期選擇框,選擇完畢后,更新到self.start_date和self.end_date,并立即調(diào)用update_note_label函數(shù)。
????????添加 右鍵窗口顯示“修改note”子菜單,點(diǎn)擊后,彈出內(nèi)容輸入框,輸入框默認(rèn)顯示“小鋒學(xué)長生活大爆炸”。點(diǎn)擊確認(rèn)后,輸入框的內(nèi)容更新到self.text_label。只需要給出修改的關(guān)鍵代碼。
????????啟動(dòng)時(shí)從http://xfxuezhang.cn/web/share/version獲取desktop_clock.txt文件,根據(jù)內(nèi)容與當(dāng)前版本是否一致,若不一致則彈窗提示有更新。
????????添加右鍵“開機(jī)自啟動(dòng)”選項(xiàng),設(shè)置后,允許pc開機(jī)后自動(dòng)啟動(dòng)當(dāng)前軟件。并且,當(dāng)設(shè)置了開機(jī)自啟動(dòng)后,再次點(diǎn)擊,應(yīng)該需要 取消開機(jī)自啟動(dòng)。
????????將一些配置參數(shù)存放入注冊(cè)表中,在啟動(dòng)軟件時(shí),從注冊(cè)表中讀取參數(shù),并更新到軟件中。當(dāng)用戶在軟件中更改了配置時(shí),需要將改動(dòng)更新到注冊(cè)表中。
代碼
給出的代碼,并經(jīng)過微調(diào):
import tkinter as tk
import datetime
import math
import locale
import os, sys
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
import winreg
# Set the locale to use UTF-8 encoding
locale.setlocale(locale.LC_ALL, 'en_US.utf8')
VERSION = '20230406'
CONFIG_REG_PATH = r'SOFTWARE\desktop_clock\Settings'
class TransparentWindow(tk.Tk):
def __init__(self, text_file=None):
super().__init__()
self.attributes('-alpha', 1) # 設(shè)置窗口透明度
# self.attributes('-topmost', True) # 窗口置頂
# self.attributes('-transparentcolor', '#000000')
self.overrideredirect(True) # 去掉窗口邊框
self.locked = False # 初始化鎖定狀態(tài)
self.mouse_x = 0
self.mouse_y = 0
self.config(bg='#000000', highlightthickness=0, bd=0)
self.window_width = 400
self.window_height = 100
# # 獲取屏幕尺寸和窗口尺寸,使窗口居中
# screen_width = self.winfo_screenwidth()
# screen_height = self.winfo_screenheight()
# x = (screen_width - self.window_width) // 2
# y = (screen_height - self.window_height) // 2
# self.geometry('{}x{}+{}+{}'.format(self.window_width, self.window_height, x, y))
# 添加日期時(shí)間標(biāo)簽
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')
# 提示標(biāo)簽
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')
# 文本標(biāo)簽
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)
# 綁定鼠標(biāo)事件
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)
# 創(chuàng)建右鍵菜單
self.menu = tk.Menu(self, tearoff=0)
self.menu.add_command(label="退出應(yīng)用", 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_text_labele)
# 添加“開機(jī)自啟動(dòng)”子菜單
self.menu.add_command(label="開機(jī)自啟", command=self.toggle_startup)
# 添加“恢復(fù)出廠設(shè)置”子菜單
self.menu.add_command(label="恢復(fù)設(shè)置", command=self.init_config_to_registry)
# 添加“關(guān)于”子菜單
self.menu.add_command(label="關(guān)于我們", command=self.about_me)
self.bind("<Button-3>", self.show_menu)
self.update_config_from_registry()
# 定時(shí)更新日期時(shí)間標(biāo)簽
self.update_datetime()
# 定時(shí)更新text標(biāo)簽
self.update_text_label()
# 定時(shí)更新note標(biāo)簽
self.update_note_label()
self.check_version()
def update_config_from_registry(self):
# Get settings from registry or set default values
self.start_date = self.get_value_from_registry('start_date', '2023/2/20', write=True)
self.end_date = self.get_value_from_registry('end_date', '2023/7/9', write=True)
startup = self.get_value_from_registry('startup', False)
self.menu.entryconfig(5, label='取消自動(dòng)' if startup else '開機(jī)自啟')
topmost = self.get_value_from_registry('topmost', False)
self.attributes('-topmost', True if topmost else False)
self.menu.entryconfig(1, label='取消置頂' if topmost else '窗口置頂')
background_color = self.get_value_from_registry('background_color', '#000000', write=True)
self.config(bg=background_color)
self.datetime_label.config(bg=background_color)
self.note_label.config(bg=background_color)
self.text_label.config(bg=background_color)
self.locked = self.get_value_from_registry('lock', False)
self.toggle_lock_button(False if self.locked else True)
self.toggle_unlock_button(True if self.locked else False)
self.text_label.configure(text=self.get_value_from_registry('text_label', '小鋒學(xué)長生活大爆炸', write=True))
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
win_x = (screen_width - self.window_width) // 2
win_y = (screen_height - self.window_height) // 2
x = self.get_value_from_registry('win_x', str(win_x))
y = self.get_value_from_registry('win_y', str(win_y))
self.geometry('{}x{}+{}+{}'.format(self.window_width, self.window_height, x, y))
def init_config_to_registry(self, first=False):
self.set_value_to_registry('start_date', '2023/2/20')
self.set_value_to_registry('end_date', '2023/7/9')
self.set_value_to_registry('startup', None)
self.set_value_to_registry('topmost', None)
self.set_value_to_registry('background_color', '#000000')
self.set_value_to_registry('lock', None)
self.set_value_to_registry('text_label', '小鋒學(xué)長生活大爆炸')
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x = (screen_width - self.window_width) // 2
y = (screen_height - self.window_height) // 2
self.set_value_to_registry('win_x', str(x))
self.set_value_to_registry('win_y', str(y))
if not first:
messagebox.showinfo("提示", "重啟生效")
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('更新提示', '發(fā)現(xiàn)新版本,是否前往藍(lán)奏云下載?密碼:c9o1'):
webbrowser.open('https://xfxuezhang.lanzouo.com/b09ubrasb')
except:
pass
def get_value_from_registry(self, query, default=None, write=False, vtype=winreg.REG_SZ):
# 從注冊(cè)表中讀取參數(shù),如果沒有,則使用默認(rèn)值
try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, CONFIG_REG_PATH, access=winreg.KEY_READ) as key:
value = winreg.QueryValueEx(key, query)[0]
except:
value = default
if write:
# 將默認(rèn)值存儲(chǔ)到注冊(cè)表中
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, CONFIG_REG_PATH) as key:
winreg.SetValueEx(key, query, 0, vtype, default)
return value
def set_value_to_registry(self, query, value=None, vtype=winreg.REG_SZ):
if value is not None:
with winreg.CreateKey(winreg.HKEY_CURRENT_USER, CONFIG_REG_PATH) as key:
winreg.SetValueEx(key, query, 0, vtype, value)
else:
try:
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, CONFIG_REG_PATH, access=winreg.KEY_ALL_ACCESS) as key:
winreg.DeleteValue(key, query)
except:
pass
def check_startup_enabled(self):
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
access=winreg.KEY_READ)
app_path = os.path.abspath(sys.argv[0])
app_name = os.path.basename(app_path)
try:
value, type = winreg.QueryValueEx(key, app_name)
except WindowsError:
return False
return value == app_path
def toggle_startup(self):
key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
access=winreg.KEY_ALL_ACCESS)
app_path = os.path.abspath(sys.argv[0])
app_name = os.path.basename(app_path)
if self.check_startup_enabled():
winreg.DeleteValue(key, app_name)
self.menu.entryconfig(5, label='開機(jī)自啟')
messagebox.showinfo("提示", "已取消開機(jī)自啟動(dòng)")
else:
winreg.SetValueEx(key, app_name, 0, winreg.REG_SZ, app_path)
self.menu.entryconfig(5, label='取消自啟')
messagebox.showinfo("提示", "已設(shè)置開機(jī)自啟動(dòng)")
key.Close()
self.set_value_to_registry('startup', '1' if self.check_startup_enabled() else None)
def about_me(self):
# webbrowser.open_new_tab('http://www.xfxuezhang.cn')
messagebox.showinfo("關(guān)于", "暫時(shí)沒什么內(nèi)容")
# 選擇日期
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='結(jié)束日期:').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()
self.set_value_to_registry('start_date', self.start_date)
self.set_value_to_registry('end_date', self.end_date)
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='取消置頂')
self.set_value_to_registry('topmost', '1' if self.attributes('-topmost') else None)
# 改變背景色
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)
self.set_value_to_registry('background_color', 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)
self.set_value_to_registry('lock', '1' if self.locked else None)
# self.set_value_to_registry('winfo_screenwidth', self.winfo_x() - self.mouse_x)
# 顯示右鍵菜單
def show_menu(self, event):
self.menu.post(event.x_root, event.y_root)
# 更新日期時(shí)間
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文檔內(nèi)容
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.get_value_from_registry('text_label', '小鋒學(xué)長生活大爆炸')
if now:
self.text_label.configure(text=now)
# self.after(1000, self.update_text_label)
def edit_text_labele(self):
"""打開文本輸入框并更新內(nèi)容"""
# 創(chuàng)建文本輸入框并顯示默認(rèn)內(nèi)容
note = tkinter.simpledialog.askstring('修改Note', '請(qǐng)輸入新的note', initialvalue=self.text_label['text'], parent=self)
# 如果用戶點(diǎn)擊確認(rèn),則更新文本標(biāo)簽的內(nèi)容
if note:
self.text_label['text'] = note
self.set_value_to_registry('text_label', 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()
# 計(jì)算距離指定日期過了多少周
start_delta = today - specified_start_date
num_of_weeks = math.ceil(start_delta.days / 7)
# 計(jì)算距離指定日期剩余多少周
end_delta = specified_end_date - today
remain_weeks = math.ceil(end_delta.days / 7)
msg = f'當(dāng)前第{num_of_weeks}周, 剩余{remain_weeks}周({end_delta.days}天)'
self.note_label.configure(text=msg)
self.after(1000*60, self.update_note_label)
# 實(shí)現(xiàn)窗口拖動(dòng)
def on_left_button_down(self, event):
self.mouse_x = event.x
self.mouse_y = event.y
# 實(shí)現(xiàn)窗口拖動(dòng)
def on_left_button_up(self, event):
x = self.winfo_x() + event.x - self.mouse_x
y = self.winfo_y() + event.y - self.mouse_y
self.mouse_x = 0
self.mouse_y = 0
self.set_value_to_registry('win_x', str(x))
self.set_value_to_registry('win_y', str(y))
# 實(shí)現(xiàn)窗口拖動(dòng)
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()
效果
界面上鼠標(biāo)點(diǎn)擊右鍵可以選擇“退出”:
鼠標(biāo)移動(dòng)到界面,會(huì)顯示“鎖定”和“解除鎖定”按鈕:
說明
????????關(guān)于背景顏色、日期等等內(nèi)容,大家可以修改相應(yīng)的代碼。文章來源:http://www.zghlxwxcb.cn/news/detail-469287.html
下載
https://xfxuezhang.lanzouo.com/b09ubrasb
密碼:c9o1文章來源地址http://www.zghlxwxcb.cn/news/detail-469287.html
到了這里,關(guān)于【教程】使用ChatGPT制作基于Tkinter的桌面時(shí)鐘的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!