鼠标失去聚焦,文字输入会跳出,不断刷新桌面解决办法

本文介绍如何修改HKEY_CURRENT_USERControlPanelDesktop下的ForegroundLockTimeout项,避免软件安装或优化过程中导致鼠标锁定聚焦时间被改为0的问题。系统默认设置为200秒。
部署运行你感兴趣的模型镜像

HKEY_CURRENT_USER\Control Panel\Desktop下的ForegroundLockTimeout项里,有些软件安装或者优化时会改成0,意思为鼠标锁定聚焦时间为0,,系统默认是十进制的200000,也就是200秒锁定时间。

注意:如果重启后会被改回去,开机启动项里检查一下关闭不必要的软件。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

基于下面的代码修改以实现下述的功能,将所有弹出来的窗口的位置居中,而不是出现在左上角。只用输出修改部分代码,不用给全部代码。 import tkinter as tk from tkinter import simpledialog, messagebox, scrolledtext, ttk import time import threading import json import os import platform from cryptography.fernet import Fernet from pynput import mouse, keyboard import sys import subprocess import csv import pandas as pd # 配置参数(常量使用大写) IDLE_THRESHOLD = 5 # 3分钟空闲间(秒) COUNTDOWN_DURATION = 10 # 锁屏倒计(秒) KEY_FILE = "system_secret.key" # 加密密钥文件名 LOG_FILE = "secure_usage_log.log" # 操作日志文件路径 ADMIN_PASSWORD = "123" # 管理员密码 LOCK_SCREEN_BG = "#000000" # 锁屏背景色(黑色) LOGIN_BG = "#2c3e50" # 登录界面背景色(深蓝色) BUTTON_BG = "#3498db" # 按钮背景色(亮蓝色) USER_FILE = r"C:\Users\x00708\PycharmProjects\mission\practice_from_work_pycharm\lock monitor\培训通过人员名单.csv" # 用户名单文件路径 USER_MANAGEMENT_PASSWORD = ADMIN_PASSWORD # 用户管理密码设置为管理员密码 # 培训通过人员名单(工号:密码) # 修改全局用户加载逻辑 def load_trained_users(file_path): """ 从CSV文件加载培训通过人员名单 文件格式要求:工号,密码 返回字典 {工号: 密码} """ users = {} try: # 检查文件是否存在 if not os.path.exists(file_path): print(f"用户文件 {file_path} 不存在,创建初始管理员账号") # 创建只包含管理员的初始用户名单 users = {"ADMIN": ADMIN_PASSWORD} # 保存加密的用户名单 save_user_file(users, file_path) return users # 加载加密密钥 if not os.path.exists(KEY_FILE): key = Fernet.generate_key() with open(KEY_FILE, "wb") as f: f.write(key) with open(KEY_FILE, "rb") as f: key = f.read() cipher = Fernet(key) # 解密用户数据 with open(file_path, "rb") as f: encrypted_data = f.read() decrypted_data = cipher.decrypt(encrypted_data) return json.loads(decrypted_data) except Exception as e: print(f"加载用户名单错误: {str(e)}") # 返回只包含管理员的用户名单 return {"ADMIN": ADMIN_PASSWORD} # 添加保存用户文件的函数 def save_user_file(users, file_path): """保存用户字典到CSV文件""" try: # 确保密钥存在 if not os.path.exists(KEY_FILE): key = Fernet.generate_key() with open(KEY_FILE, "wb") as f: f.write(key) with open(KEY_FILE, "rb") as f: key = f.read() cipher = Fernet(key) # 加密用户数据 encrypted_data = cipher.encrypt(json.dumps(users).encode()) with open(file_path, "wb") as f: f.write(encrypted_data) return True except Exception as e: print(f"保存用户文件出错: {str(e)}") return False # 从文件加载培训通过人员名单 TRAINED_USERS = load_trained_users(USER_FILE) # 确保管理员账户存在 if "ADMIN" not in TRAINED_USERS: TRAINED_USERS["ADMIN"] = ADMIN_PASSWORD save_user_file(TRAINED_USERS, USER_FILE) class SecureDesktopMonitor: def __init__(self): # 创建主窗口 self.root = tk.Tk() # 创建主窗口对象 self.root.title("安全桌面监控系统") # 设置窗口标题 self.root.geometry("800x600") # 初始窗口尺寸 self.root.configure(bg=LOGIN_BG) # 设置背景色 # 设置窗口在最顶层 self.root.attributes("-topmost", True) # 系统状态变量,防止用户绕过监控 self.current_user = None # 当前登录用户(未登录为None) self.login_time = 0 # 登陆间(初始为0) self.last_activity = time.time() # 最后活动间(初始化为当前间) self.idle_timer = None # 空闲检测定器(用于推迟锁屏) self.countdown_timer = None # 倒计器(锁屏前提示) self.listening = False # 监听器状态标志 self.is_locked = False # 界面锁屏状态(初始为True,即未登录锁定) # 创建鼠标键盘监听器 self.mouse_listener = mouse.Listener(on_move=self.activity_detected) # 鼠标移动触发活动检测 self.keyboard_listener = keyboard.Listener(on_press=self.activity_detected) # 键盘按键触发活动检测 # 显示初始登录界面 self.show_login_screen() # Tkinter事件循环(阻塞式,保持程序运行),mainloop()是Tkinter的核心,用于处理用户事件(如点击、输入) self.root.mainloop() def show_login_screen(self): """显示登录界面""" self.clear_screen() # 清空当前屏幕所有内容 self.is_locked = True # 标记系统为锁定状态 # 设置全屏模式(防止用户切换窗口) self.root.attributes('-fullscreen', True) # 创建居中主框架 main_frame = tk.Frame(self.root, bg=LOGIN_BG) # bg颜色深蓝色 main_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # 使用place布局精确居中 # 系统标题标签 title = tk.Label( main_frame, text="安全桌面登录", font=("Arial", 24, "bold"), # 字体族、大小、粗体 fg="white", # 前景色(白色) bg=LOGIN_BG # 背景色与界面一致 ) title.pack(pady=20) # 打包布局,垂直间距20像素 # 登录表单框架(使用grid布局对齐输入框) form_frame = tk.Frame(main_frame, bg=LOGIN_BG) form_frame.pack(pady=20) # 工号输入标签和输入框 tk.Label( form_frame, # 框架格式 text="工号:", font=("黑体", 14), fg="white", bg=LOGIN_BG ).grid(row=0, column=0, padx=10, pady=10, sticky="e") self.id_entry = tk.Entry(form_frame, font=("Arial", 14), width=20) # 单行文本输入框 self.id_entry.grid(row=0, column=1, padx=10, pady=10) self.id_entry.focus_set() # 自动聚焦到工号输入框(提升用户体验) # 密码输入标签和输入框(内容显示为*号) tk.Label( form_frame, text="密码:", font=("黑体", 14), fg="white", bg=LOGIN_BG ).grid(row=1, column=0, padx=10, pady=10, sticky="e") self.pw_entry = tk.Entry(form_frame, show="*", font=("Arial", 14), width=20) # show="*" 隐藏输入 self.pw_entry.grid(row=1, column=1, padx=10, pady=10) # 放置位置 # 绑定回车键(用户输入密码后按回车可直接登录) self.pw_entry.bind("<Return>", lambda event: self.authenticate_user()) # 登录按钮 login_btn = tk.Button( form_frame, text="登 录", command=self.authenticate_user, # 点击触发认证方法 font=("黑体", 18, "bold"), bg=BUTTON_BG, # 按钮背景色 fg="white", # 按钮文字颜色 width=15, height=2 ) login_btn.grid(row=2, column=0, columnspan=2, pady=20) # 放置位置跨两列居中 # 系统信息 sys_info = tk.Label( main_frame, text="用户使用长监测系统 | 仅限授权人员使用", font=("黑体", 10), fg="#bdc3c7", bg=LOGIN_BG ) sys_info.pack(side=tk.BOTTOM, pady=10) def authenticate_user(self): """验证用户身份(首次登录设置密码)""" user_id = self.id_entry.get().strip() # 获取用户id和密码 password = self.pw_entry.get().strip() # 检查是否是管理员登录且用户名单只有管理员 is_only_admin = len(TRAINED_USERS) == 1 and "ADMIN" in TRAINED_USERS # 检查用户是否存在 if user_id in TRAINED_USERS: # 如果是管理员且用户名单为空,直接进入用户管理界面 if is_only_admin and user_id == "ADMIN": self.current_user = user_id self.login_time = time.time() self.last_activity = self.login_time self.is_locked = False self.manage_users() # 直接进入用户管理 return # 处理首次登录(密码为空) if TRAINED_USERS[user_id] == "": self.set_initial_password(user_id) return # 如果id和密码匹配,则正常启动桌面会话 if TRAINED_USERS[user_id] == password: self.current_user = user_id self.login_time = time.time() self.last_activity = self.login_time self.is_locked = False self.start_desktop_session() # 开始桌面会话函数 return else: messagebox.showerror("访问拒绝", "输入密码有误,请重新输入!") self.pw_entry.delete(0, tk.END) return # 如果用户名单只有管理员,给出特定提示 if is_only_admin: messagebox.showerror("访问拒绝", "当前只有管理员可以登录系统,请使用管理员账号登录") else: messagebox.showerror("访问拒绝", "未授权操作!禁止访问系统!") # 清空密码框 self.pw_entry.delete(0, tk.END) # 新用户首次登陆设置密码 def set_initial_password(self, user_id): """新用户首次登录设置密码""" dialog = tk.Toplevel(self.root) dialog.title("设置初始密码") dialog.geometry("300x200") dialog.transient(self.root) dialog.grab_set() tk.Label(dialog, text=f"欢迎新用户 {user_id}").pack(pady=(10, 0)) tk.Label(dialog, text="请设置您的初始密码:").pack(pady=(10, 0)) password_entry = tk.Entry(dialog, show="*", width=20) password_entry.pack() tk.Label(dialog, text="确认密码:").pack(pady=(10, 0)) confirm_entry = tk.Entry(dialog, show="*", width=20) confirm_entry.pack() def save_password(): password = password_entry.get().strip() confirm = confirm_entry.get().strip() if not password: messagebox.showerror("错误", "密码不能为空", parent=dialog) return if password != confirm: messagebox.showerror("错误", "两次输入的密码不一致", parent=dialog) return # 更新密码 TRAINED_USERS[user_id] = password save_user_file(TRAINED_USERS, USER_FILE) # 完成设置 dialog.destroy() messagebox.showinfo("成功", "密码设置成功!") # 自动登录 self.current_user = user_id self.login_time = time.time() self.last_activity = self.login_time self.is_locked = False self.start_desktop_session() tk.Button(dialog, text="保存", command=save_password).pack(pady=10) def start_desktop_session(self): """开始桌面会话""" self.clear_screen() self.root.attributes('-fullscreen', False) self.root.geometry("400x400") self.root.title(f"使用中 - 用户: {self.current_user}") # 停止可能存在的旧监听器 self.stop_activity_monitoring() # 启动新的监听 self.start_activity_monitoring() # 显示桌面内容 desktop_frame = tk.Frame(self.root) desktop_frame.pack(fill=tk.BOTH, expand=True) # expand可将组件由其势力范围扩大到扩展范围 # 欢迎信息 welcome_msg = tk.Label( desktop_frame, text=f"欢迎, {self.current_user}", font=("Arial", 22, "bold"), pady=40 ) welcome_msg.pack() # 状态信息 status_text = tk.Label( desktop_frame, text="桌面已解锁 - 工作中...", font=("黑体", 14), fg="green" ) status_text.pack(pady=15) # 使用间显示 self.time_label = tk.Label( desktop_frame, text="使用间: 00:00", font=("黑体", 12) ) self.time_label.pack(pady=10) # 手动锁定按钮 lock_btn = tk.Button( desktop_frame, text="锁定系统", command=self.lock_system, # 调用锁定系统函数 font=("黑体", 12), bg="#e74c3c", fg="white" ) lock_btn.pack(pady=20) # lock_btn为变量名对象,pack为tkinter的几何布局管理器,可自动排列控件 # ⭐管理员按钮组框架 admin_frame = tk.Frame(desktop_frame) admin_frame.pack(pady=10) # 管理员查看记录按钮(仅管理员可见) if self.current_user == "ADMIN": admin_btn = tk.Button( admin_frame, text="管理员查看记录", command=self.admin_view, font=("黑体", 12), bg="#F5FFFA", fg="#e74c3c" ) admin_btn.pack(side=tk.LEFT, padx=5) # 新增:管理用户名单按钮(仅管理员可见) manage_users_btn = tk.Button( admin_frame, text="管理用户名单", command=self.manage_users, font=("黑体", 12), bg="#F5FFFA", fg="#e74c3c" ) manage_users_btn.pack(side=tk.LEFT, padx=5) # 启动鼠标键盘事件监听 self.start_activity_monitoring() # 鼠标键盘监听函数 # 开始空闲检测 self.start_idle_monitor() # 开始更新使用间显示 self.update_usage_time() # 管理员管理培训通过名单⭐ def manage_users(self): """管理员管理用户名单""" # 如果是首次登录(只有管理员),跳过密码验证 if len(TRAINED_USERS) > 1 or "ADMIN" not in TRAINED_USERS: # 验证管理员密码 password = simpledialog.askstring("管理员认证", "请输入管理员密码:", show='*') if password != ADMIN_PASSWORD: messagebox.showerror("认证失败", "密码错误!") return # 如果是首次登录(只有管理员),显示特殊提示 is_only_admin = len(TRAINED_USERS) == 1 and "ADMIN" in TRAINED_USERS self.clear_screen() self.root.title("用户名单管理") self.root.geometry("800x600") # 标题 title = tk.Label( self.root, text="用户名单管理", font=("Arial", 24, "bold"), pady=20, bg=LOGIN_BG, fg="white" ) title.pack() # 如果是首次登录,显示提示信息 if is_only_admin: prompt = tk.Label( self.root, text="首次使用请添加至少一个普通用户账号", font=("黑体", 14), fg="red", pady=10 ) prompt.pack() # 框架容器 container = tk.Frame(self.root) container.pack(fill=tk.BOTH, expand=True, padx=20, pady=10) # both指定容器在X和Y两个方向上填充父容器分配的空间, expand容器会随着父容器的扩大而扩展, pady设置容器的外间距(边距) # 创建Treeview显示用户(只显示工号) columns = ("工号",) # 单元素元组需要加逗号 self.user_tree = ttk.Treeview(container, columns=columns, show="headings", selectmode="browse") # 设置列标题 for col in columns: self.user_tree.heading(col, text=col) self.user_tree.column(col, width=100, anchor=tk.CENTER) # 添加滚动条 scrollbar = ttk.Scrollbar(container, orient=tk.VERTICAL, command=self.user_tree.yview) self.user_tree.configure(yscroll=scrollbar.set) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.user_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 刷新用户列表 self.refresh_user_list() # 按钮框架 btn_frame = tk.Frame(self.root) btn_frame.pack(pady=20) # 添加用户按钮 add_btn = tk.Button( btn_frame, text="添加用户", command=self.add_user, font=("黑体", 12), bg="#2ecc71", fg="white" ) add_btn.pack(side=tk.LEFT, padx=10) # 删除用户按钮 delete_btn = tk.Button( btn_frame, text="删除用户", command=self.delete_user, font=("黑体", 12), bg="#e74c3c", fg="white" ) delete_btn.pack(side=tk.LEFT, padx=10) # 导出用户名单按钮 export_users_btn = tk.Button( btn_frame, text="导出文件", command=self.export_users_csv, font=("黑体", 12), bg=BUTTON_BG, fg="white" ) export_users_btn.pack(side=tk.LEFT, padx=10) # 返回按钮 back_btn = tk.Button( btn_frame, text="返回桌面", command=self.start_desktop_session, font=("黑体", 12), bg=BUTTON_BG, fg="white" ) back_btn.pack(side=tk.LEFT, padx=10) def refresh_user_list(self): """刷新用户列表显示(只显示工号)""" # 清除现有数据 for item in self.user_tree.get_children(): self.user_tree.delete(item) # 添加用户数据(只显示工号) for user_id in TRAINED_USERS.keys(): self.user_tree.insert("", tk.END, values=(user_id,)) def add_user(self): """添加新用户(只添加工号,密码为空)""" dialog = tk.Toplevel(self.root) dialog.title("添加新用户") dialog.geometry("300x200") dialog.transient(self.root) dialog.grab_set() # 只要求输入工号(不需要密码) tk.Label(dialog, text="工号:").pack(pady=(10, 0)) id_entry = tk.Entry(dialog, width=20) id_entry.pack() # tk.Label(dialog, text="密码:").pack(pady=(10, 0)) # password_entry = tk.Entry(dialog, show="*", width=20) # password_entry.pack() def save_new_user(): user_id = id_entry.get().strip() if not user_id: messagebox.showerror("错误", "工号不能为空", parent=dialog) return if user_id in TRAINED_USERS: messagebox.showerror("错误", "该工号已存在", parent=dialog) return # 添加到全局用户列表(密码初始化为空字符串) TRAINED_USERS[user_id] = "" # 设置初始密码为空 save_user_file(TRAINED_USERS, USER_FILE) # 刷新显示 self.refresh_user_list() dialog.destroy() messagebox.showinfo("成功", f"用户 {user_id} 添加成功") tk.Button(dialog, text="保存", command=save_new_user).pack(pady=20) def delete_user(self): """删除选中用户""" selected = self.user_tree.selection() if not selected: messagebox.showerror("错误", "请先选择一个用户") return item = selected[0] values = self.user_tree.item(item, "values") user_id = values[0] if user_id == "ADMIN": messagebox.showerror("错误", "不能删除管理员账户") return if messagebox.askyesno("确认", f"确定要删除用户 {user_id} 吗?"): # 从全局用户列表中删除 if user_id in TRAINED_USERS: del TRAINED_USERS[user_id] save_user_file(TRAINED_USERS, USER_FILE) self.refresh_user_list() messagebox.showinfo("成功", f"用户 {user_id} 已删除") def update_usage_time(self): """更新使用间显示""" if not self.is_locked: # 如果没有锁 usage_seconds = time.time() - self.login_time minutes, seconds = divmod(int(usage_seconds), 60) self.time_label.config(text=f"使用间: {minutes:02d}:{seconds:02d}") self.root.after(1000, self.update_usage_time) # 1s后更新间显示 def start_activity_monitoring(self): """启动鼠标键盘事件监听""" # 如果已有监听器在运行,先停止 if self.listening: self.stop_activity_monitoring() # 创建新的监听器实例 self.mouse_listener = mouse.Listener(on_move=self.activity_detected) self.keyboard_listener = keyboard.Listener(on_press=self.activity_detected) # 启动线程 mouse_thread = threading.Thread(target=self.mouse_listener.start) keyboard_thread = threading.Thread(target=self.keyboard_listener.start) mouse_thread.daemon = True keyboard_thread.daemon = True mouse_thread.start() keyboard_thread.start() self.listening = True # if not self.listening: # mouse_thread = threading.Thread(target=self.mouse_listener.start) # 启动鼠标事件监听线程 # keyboard_thread = threading.Thread(target=self.keyboard_listener.start) # 启动键盘事件监听线程 # mouse_thread.daemon = True # daemon=True 将线程设为守护模式,意味着当主程序退出,这两个线程会被强制终止,不会阻碍程序关闭 # keyboard_thread.daemon = True # mouse_thread.start() # keyboard_thread.start() # self.listening = True # 标记监听状态已激活,防止方法被重复调用 def stop_activity_monitoring(self): """停止鼠标键盘事件监听""" if self.listening: if self.mouse_listener: self.mouse_listener.stop() if self.keyboard_listener: self.keyboard_listener.stop() self.mouse_listener = None self.keyboard_listener = None self.listening = False # if self.listening: # self.mouse_listener.stop() # self.keyboard_listener.stop() # self.listening = False def activity_detected(self, *args): """检测到用户活动""" if not self.is_locked: # 系统未被锁定 self.last_activity = time.time() # 更新最后活动间 # ⭐ 修改点1:确保在倒计期间检测到活动重新启动监听 if self.countdown_timer: # 如果倒计正在进行 self.root.after_cancel(self.countdown_timer) self.countdown_timer = None # 重新启动桌面会话和监听 self.stop_activity_monitoring() # 先停止当前监听 self.clear_screen() self.start_desktop_session() # 这会重新启动监听 def start_idle_monitor(self): """监控空闲状态""" if not self.is_locked: idle_time = time.time() - self.last_activity if idle_time > IDLE_THRESHOLD: # 空闲超 self.start_lock_countdown() else: # 每秒检查一次 self.idle_timer = self.root.after(1000, self.start_idle_monitor) def start_lock_countdown(self): """开始锁屏倒计""" self.clear_screen() self.root.configure(bg=LOCK_SCREEN_BG) self.root.attributes('-fullscreen', True) # 倒计显示 self.countdown = COUNTDOWN_DURATION self.countdown_label = tk.Label( self.root, text=f"系统将在 {self.countdown} 秒后锁定...", font=("Arial", 36, "bold"), fg="red", bg=LOCK_SCREEN_BG ) self.countdown_label.place(relx=0.5, rely=0.4, anchor=tk.CENTER) # 提示信息 prompt = tk.Label( self.root, text="检测到系统空闲,移动鼠标或按键取消锁定", font=("Arial", 20), fg="#3498db", bg=LOCK_SCREEN_BG ) prompt.place(relx=0.5, rely=0.5, anchor=tk.CENTER) # 用户信息 user_info = tk.Label( self.root, text=f"当前用户: {self.current_user}", font=("Arial", 16), fg="white", bg=LOCK_SCREEN_BG ) user_info.place(relx=0.5, rely=0.6, anchor=tk.CENTER) # 开始倒计 self.update_countdown() def update_countdown(self): """更新倒计显示""" self.countdown -= 1 self.countdown_label.config(text=f"系统将在 {self.countdown} 秒后锁定...") if self.countdown <= 0: self.lock_system() else: # 每秒检查一次 self.countdown_timer = self.root.after(1000, self.update_countdown) def lock_system(self, manual=False): """锁定系统并保存使用记录""" logout_time = time.time() usage_seconds = logout_time - self.login_time # 格式化使用间 minutes, seconds = divmod(int(usage_seconds), 60) usage_time = f"{minutes:02d}:{seconds:02d}" # 创建记录 record = { "user_id": self.current_user, "login_time": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.login_time)), "logout_time": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(logout_time)), "usage_duration": usage_time # "lock_type": "手动" if manual else "自动" } # 加密保存记录 self.save_usage_record(record) # 停止监听和计器 if self.idle_timer: self.root.after_cancel(self.idle_timer) if self.countdown_timer: self.root.after_cancel(self.countdown_timer) self.stop_activity_monitoring() # 重置用户状态 self.current_user = None self.is_locked = True # 显示登录界面 self.show_login_screen() def save_usage_record(self, record): """加密保存使用记录""" # 生成或加载加密密钥 if not os.path.exists(KEY_FILE): # 检查密钥文件是否存在 key = Fernet.generate_key() # 若不存在(首次运行),Fernet.generate_key()生成一个新的对称加密密钥(256位),并以二进制模式写入文件 with open(KEY_FILE, "wb") as f: f.write(key) with open(KEY_FILE, "rb") as f: # 如果已存在,直接读取密钥内容 key = f.read() cipher = Fernet(key) # 创建Fernet加密器实例.Fernet是AES加密的封装库,提供简单易用的对称加密功能 # 读取已有记录,避免新记录覆盖旧数据 records = [] if os.path.exists(LOG_FILE): # 检查日志文件是否存在 with open(LOG_FILE, "rb") as f: # 如果存在,以二进制模式读取加密数据 encrypted_data = f.read() decrypted_data = cipher.decrypt(encrypted_data) # 使用cipher.decrypt()解密 records = json.loads(decrypted_data) # 通过json.loads()将JSON字符串解析为Python列表 # 添加新记录 records.append(record) # 加密保存 encrypted_data = cipher.encrypt(json.dumps(records).encode()) # 将整个记录列表重新加密 with open(LOG_FILE, "wb") as f: f.write(encrypted_data) # 管理员管理使用记录⭐ def admin_view(self): """管理员查看使用记录""" password = simpledialog.askstring("管理员认证", "请输入管理员密码:", show='*') if password == ADMIN_PASSWORD: records = self.get_usage_records() # 获取使用记录函数 self.display_records(records) # 显示使用记录函数 else: messagebox.showerror("认证失败", "密码错误!") # 密码框 def get_usage_records(self): """获取使用记录(解密)""" if not os.path.exists(KEY_FILE) or not os.path.exists(LOG_FILE): return [] try: with open(KEY_FILE, "rb") as f: key = f.read() cipher = Fernet(key) with open(LOG_FILE, "rb") as f: encrypted_data = f.read() decrypted_data = cipher.decrypt(encrypted_data) return json.loads(decrypted_data) except: return [] def display_records(self, records): """显示使用记录""" self.clear_screen() self.root.title("使用记录 - 管理员视图") self.root.geometry("1000x700") # 标题 title = tk.Label( self.root, text="电脑使用记录 - 安全报告", font=("Arial", 24, "bold"), pady=20, bg=LOGIN_BG, fg="white" ) title.pack() # 滚动文本框 text_area = scrolledtext.ScrolledText( self.root, wrap=tk.WORD, font=("Consolas", 12), width=120, height=30 ) text_area.pack(padx=20, pady=3, fill=tk.BOTH, expand=True) # 添加表头 header = "工号 登录间 登出间 使用间\n" text_area.insert(tk.INSERT, header) text_area.insert(tk.INSERT, "-" * 65 + "\n") # 添加记录 for record in records: line = ( f"{record['user_id']:<8} " f"{record['login_time']:<20} " f"{record['logout_time']:<20} " f"{record['usage_duration']:<8}\n" # f"{record.get('lock_type', '自动'):<8}\n" ) text_area.insert(tk.INSERT, line) text_area.configure(state='disabled') # 设为只读 # 添加返回桌面按钮 btn_frame = tk.Frame(self.root) btn_frame.pack(pady=5) # pady参数在垂直方向(上下)添加10像素的填充,确保与其他界面元素有足够的间距 # 导出记录按钮 tk.Button( btn_frame, text="导出文件", command=lambda: self.export_records_csv(records), font=("黑体", 12), bg=BUTTON_BG, fg="white", width=15 ).pack(side=tk.LEFT, padx=10) # 返回按钮 tk.Button( btn_frame, text="返回桌面", command=self.start_desktop_session, font=("黑体", 12), bg=BUTTON_BG, fg="white", width=15 ).pack(side=tk.LEFT, padx=10) # # tk.Button( # btn_frame, # text="返回登录界面", # command=self.show_login_screen, # font=("黑体", 12), # bg=BUTTON_BG, # fg="white", # width=20 # ).pack(side=tk.LEFT, padx=10) # 将使用记录和人员名单导出 def export_records_csv(self, records): """导出使用记录为CSV文件""" try: # 获取当前间作为文件名 timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime()) filename = f"使用记录_{timestamp}.csv" with open(filename, 'w', newline='', encoding='utf-8') as file: writer = csv.writer(file) # 写入表头 writer.writerow(["工号", "登录间", "登出间", "使用间"]) # 写入每条记录 for record in records: writer.writerow([ record['user_id'], record['login_time'], record['logout_time'], record['usage_duration'] ]) # ⭐导出为excel表格 # try: # # 获取当前间作为文件名 # timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime()) # filename = f"使用记录_{timestamp}.xlsx" # # # 创建DataFrame # data = { # "工号": [record['user_id'] for record in records], # "登录间": [record['login_time'] for record in records], # "登出间": [record['logout_time'] for record in records], # "使用间": [record['usage_duration'] for record in records] # } # df = pd.DataFrame(data) # # # 导出到Excel # df.to_excel(filename, index=False, engine='openpyxl') # messagebox.showinfo("导出成功", f"使用记录已导出到: {os.path.abspath(filename)}") except Exception as e: messagebox.showerror("导出失败", f"导出使用记录出错: {str(e)}") def export_users_csv(self): """导出用户名单为CSV文件(解密后导出只包含工号)""" try: # 获取当前间作为文件名 timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime()) filename = f"用户名单_{timestamp}.csv" with open(filename, 'w', newline='', encoding='utf-8') as file: writer = csv.writer(file) # 写入表头(只包含工号) writer.writerow(["工号"]) # 写入每条记录(只导出工号) for user_id in TRAINED_USERS.keys(): writer.writerow([user_id]) messagebox.showinfo("导出成功", f"用户名单已解密并导出到: {os.path.abspath(filename)}") except Exception as e: messagebox.showerror("导出失败", f"导出用户名单出错: {str(e)}") """导出excel文件""" # try: # timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime()) # filename = f"用户名单_{timestamp}.xlsx" # # # 创建dataframe # data = [] # for user_id, password in TRAINED_USERS.items(): # data.append([user_id, password]) # df = pd.DataFrame(data, columns=["工号", "密码"]) # # # 导出到excel # df.to_excel(filename, index=False, engine='openpyxl') def clear_screen(self): """清除当前屏幕所有内容""" for widget in self.root.winfo_children(): widget.destroy() def lock_on_close(self): """关闭窗口锁定系统""" if self.current_user: self.lock_system(manual=True) self.root.destroy() # 启动系统 if __name__ == "__main__": app = SecureDesktopMonitor() # 绑定窗口关闭事件 app.root.protocol("WM_DELETE_WINDOW", app.lock_on_close)
最新发布
10-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值