feat: 初始化项目
This commit is contained in:
commit
fed6c361a5
|
|
@ -0,0 +1,91 @@
|
|||
# Byte-compiled / optimized / DLL files[1](@ref)[3](@ref)[8](@ref)
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.pyc
|
||||
*.so
|
||||
|
||||
# PyInstaller distribution / packaging[1](@ref)[3](@ref)[8](@ref)
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller specific files[1](@ref)[3](@ref)[8](@ref)
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs[1](@ref)[3](@ref)[8](@ref)
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports[1](@ref)[3](@ref)[8](@ref)
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Virtual environments[1](@ref)[2](@ref)[7](@ref)
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# macOS specific files[1](@ref)[2](@ref)[6](@ref)
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
Icon
|
||||
._*
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# IDE and editor files[1](@ref)[4](@ref)[6](@ref)
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.ropeproject
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Other common files
|
||||
*.log
|
||||
*.tmp
|
||||
*.bak
|
||||
|
|
@ -0,0 +1 @@
|
|||
3.13.0
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
## 打包
|
||||
|
||||
在 windows 中打开 powersehll 执行下面命令
|
||||
|
||||
```shell
|
||||
# 安装依赖
|
||||
pip3 install -r requirements.txt
|
||||
# 打包
|
||||
python3 -m PyInstaller --onefile --windowed --icon=app.ico --name=ShutdownTimer app.py
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
import threading
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
class ShutdownTimerApp:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("定时关机程序")
|
||||
self.root.geometry("400x280")
|
||||
self.root.minsize(400, 280) # 设置最小尺寸防止窗口过小
|
||||
self.root.resizable(False, False)
|
||||
|
||||
# 倒计时线程控制
|
||||
self.is_running = False
|
||||
self.timer_thread = None
|
||||
|
||||
self.create_widgets()
|
||||
|
||||
def create_widgets(self):
|
||||
# 主框架
|
||||
main_frame = ttk.Frame(self.root, padding="20")
|
||||
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# 时间输入框架
|
||||
time_frame = ttk.LabelFrame(main_frame, text="设置关机时间")
|
||||
time_frame.pack(fill=tk.X, pady=10)
|
||||
|
||||
# 时间输入和单位选择
|
||||
input_frame = ttk.Frame(time_frame)
|
||||
input_frame.pack(fill=tk.X, pady=10)
|
||||
|
||||
# 时间输入框
|
||||
ttk.Label(input_frame, text="时间:").grid(row=0, column=0, padx=5)
|
||||
self.time_var = tk.StringVar(value="10")
|
||||
self.time_entry = ttk.Entry(input_frame, textvariable=self.time_var, width=10)
|
||||
self.time_entry.grid(row=0, column=1, padx=5)
|
||||
|
||||
# 单位选择
|
||||
ttk.Label(input_frame, text="单位:").grid(row=0, column=2, padx=5)
|
||||
self.unit_var = tk.StringVar(value="分钟")
|
||||
self.unit_combo = ttk.Combobox(input_frame, textvariable=self.unit_var, values=["秒", "分钟", "小时"], state="readonly", width=8)
|
||||
self.unit_combo.grid(row=0, column=3, padx=5)
|
||||
|
||||
# 状态显示
|
||||
self.status_var = tk.StringVar(value="等待设置时间...")
|
||||
self.status_label = ttk.Label(main_frame, textvariable=self.status_var, font=("Arial", 10))
|
||||
self.status_label.pack(pady=10)
|
||||
|
||||
# 倒计时显示
|
||||
self.countdown_var = tk.StringVar(value="00:00:00")
|
||||
self.countdown_label = ttk.Label(main_frame, textvariable=self.countdown_var, font=("Arial", 16, "bold"))
|
||||
self.countdown_label.pack(pady=5)
|
||||
|
||||
# 按钮框架
|
||||
button_frame = ttk.Frame(main_frame)
|
||||
button_frame.pack(pady=15)
|
||||
|
||||
# 启动按钮
|
||||
self.start_button = ttk.Button(button_frame, text="启动关机定时", command=self.start_shutdown_timer)
|
||||
self.start_button.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
# 取消按钮
|
||||
self.cancel_button = ttk.Button(button_frame, text="取消定时", command=self.cancel_shutdown_timer, state="disabled")
|
||||
self.cancel_button.pack(side=tk.LEFT, padx=5)
|
||||
|
||||
def start_shutdown_timer(self):
|
||||
if self.is_running:
|
||||
return
|
||||
|
||||
try:
|
||||
# 获取输入的时间值
|
||||
time_value = float(self.time_var.get())
|
||||
if time_value <= 0:
|
||||
raise ValueError("时间必须大于0")
|
||||
|
||||
# 根据单位转换为秒
|
||||
unit = self.unit_var.get()
|
||||
if unit == "秒":
|
||||
total_seconds = time_value
|
||||
elif unit == "分钟":
|
||||
total_seconds = time_value * 60
|
||||
else: # 小时
|
||||
total_seconds = time_value * 3600
|
||||
|
||||
# 更新状态
|
||||
self.is_running = True
|
||||
self.start_button.config(state="disabled")
|
||||
self.cancel_button.config(state="normal")
|
||||
self.status_var.set(f"定时已启动 - {time_value} {unit}后关机")
|
||||
|
||||
# 启动倒计时线程
|
||||
self.timer_thread = threading.Thread(target=self.countdown_thread, args=(total_seconds,))
|
||||
self.timer_thread.daemon = True
|
||||
self.timer_thread.start()
|
||||
|
||||
except ValueError as e:
|
||||
messagebox.showerror("输入错误", f"请输入有效的数字: {str(e)}")
|
||||
|
||||
def cancel_shutdown_timer(self):
|
||||
self.is_running = False
|
||||
self.start_button.config(state="normal")
|
||||
self.cancel_button.config(state="disabled")
|
||||
self.status_var.set("定时已取消")
|
||||
self.countdown_var.set("00:00:00")
|
||||
|
||||
def countdown_thread(self, total_seconds):
|
||||
remaining_seconds = total_seconds
|
||||
|
||||
while remaining_seconds > 0 and self.is_running:
|
||||
# 更新倒计时显示
|
||||
hours = int(remaining_seconds // 3600)
|
||||
minutes = int((remaining_seconds % 3600) // 60)
|
||||
seconds = int(remaining_seconds % 60)
|
||||
|
||||
countdown_text = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
||||
self.countdown_var.set(countdown_text)
|
||||
|
||||
# 等待1秒
|
||||
time.sleep(1)
|
||||
remaining_seconds -= 1
|
||||
|
||||
if self.is_running and remaining_seconds <= 0:
|
||||
# 时间到,执行关机命令
|
||||
self.execute_shutdown()
|
||||
|
||||
def execute_shutdown(self):
|
||||
# 执行Windows关机命令(立即关机,无等待时间)
|
||||
try:
|
||||
# 使用/s参数表示关机,/t 0表示立即执行,/f强制关闭所有应用程序
|
||||
os.system("shutdown /s /f /t 0")
|
||||
self.status_var.set("正在关机...")
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"关机命令执行失败: {str(e)}")
|
||||
self.cancel_shutdown_timer()
|
||||
|
||||
|
||||
def main():
|
||||
root = tk.Tk()
|
||||
app = ShutdownTimerApp(root)
|
||||
root.mainloop()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1 @@
|
|||
pyinstaller
|
||||
Loading…
Reference in New Issue