当前位置: 首页 > news >正文

山东建设厅网站扫黑北京市电力建设公司网站

山东建设厅网站扫黑,北京市电力建设公司网站,如何做推广,广告投放跟网站建设一样吗#x1f4ca; 【开源解析】基于PythonQt打造智能应用时长统计工具 - 你的数字生活分析师 #x1f308; 个人主页#xff1a;创客白泽 - CSDN博客 #x1f525; 系列专栏#xff1a;#x1f40d;《Python开源项目实战》 #x1f4a1; 热爱不止于代码#xff0c;热情源自… 【开源解析】基于PythonQt打造智能应用时长统计工具 - 你的数字生活分析师 个人主页创客白泽 - CSDN博客 系列专栏《Python开源项目实战》 热爱不止于代码热情源自每一个灵感闪现的夜晚。愿以开源之火点亮前行之路。 希望大家多多支持我们一起进步 如果文章对你有帮助的话欢迎 点赞 评论 收藏 ⭐️ 加关注分享给更多人哦 概述数字时代的时间管理者 在数字化生活日益普及的今天我们每天与各种应用程序的交互时间越来越长。但你是否真正了解自己的数字生活习惯哪些应用占用了你最多的时间时间都花在了哪里 今天我将介绍一款自主研发的应用时长统计工具它能够 实时监控应用使用情况可视化展示时间分配分析每周使用趋势最小化到系统托盘后台运行 这款工具采用PythonQt开发结合matplotlib实现专业级数据可视化是程序员和普通用户都能轻松使用的效率工具。 ️ 功能全景图 核心功能矩阵 功能模块技术实现数据维度实时监控psutilwin32api跨平台采集秒级精度数据持久化JSON序列化按日期存储历史数据可追溯可视化分析MatplotlibQt5嵌入式图表多维数据呈现系统托盘QSystemTrayIcon无感后台运行周趋势分析时间序列聚合堆叠柱状图七日对比 技术栈亮点 应用识别Windows/MacOS/Linux三平台兼容性能优化定时器精准控制1秒采集间隔数据安全双重备份机制实时每日交互设计标签页自动刷新表格高亮交互 ️ 效果展示 1. 实时数据看板 特点说明 当前运行应用蓝色高亮使用时长TOP3金色标识实时刷新排名变化 2. 时长占比分析 智能处理 自动合并5%的小项为其他中心显示总时长响应式标签防重叠 3. 周趋势图谱 分析维度 Top5应用每日对比小时为单位直观显示颜色编码区分应用 ️ 部署与使用指南 环境准备 # 基础依赖 pip install pyqt5 psutil matplotlib# 平台特定依赖 # Windows pip install pywin32使用教程 python app_usage_tracker.py最小化到托盘关闭窗口自动后台运行 数据查看 实时数据页查看当前会话统计图表页点击标签自动刷新 数据存储 app_usage_data/目录下查看历史数据每日数据自动归档 自定义配置 # 修改监控频率毫秒 self.timer.start(1000) # 默认1秒# 修改数据存储路径 self.data_dir custom_data_path核心代码解析 1. 应用进程监控引擎 def get_current_app(self):跨平台应用识别核心方法try:if platform.system() Windows:import win32guiwindow win32gui.GetForegroundWindow()_, pid win32gui.GetWindowThreadProcessId(window)return psutil.Process(pid).name()# 其他平台处理...except Exception as e:print(f应用识别异常: {e})return Unknown技术要点 Windows使用win32gui获取前台窗口Linux依赖xdotool工具链MacOS通过AppKit接口 2. 数据可视化引擎 def update_weekly_chart(self):周趋势图生成逻辑# 1. 数据准备dates [datetime.now().date() - timedelta(daysi) for i in range(6, -1, -1)]# 2. Top5应用筛选app_total_time defaultdict(float)for date in dates:daily_data self.load_daily_data(date.strftime(%Y-%m-%d))for app, secs in (daily_data or {}).items():app_total_time[app] secs# 3. 柱状图绘制fig, ax plt.subplots(figsize(12,7))for i, (app, _) in enumerate(sorted(app_total_time.items(), keylambda x: x[1], reverseTrue)[:5]):daily_usage [self.load_daily_data(d.strftime(%Y-%m-%d)).get(app, 0)/3600 for d in dates]ax.bar(x i*width, daily_usage, width, labelapp)# 4. 图表美化...设计亮点 动态数据聚合自动响应式布局视觉层次分明 3. 系统托盘集成 def init_system_tray(self):托盘图标管理系统self.tray_icon QSystemTrayIcon(self)menu QMenu()menu.addAction(显示主界面, self.show)menu.addAction(退出, self.close_app)self.tray_icon.setContextMenu(menu)self.tray_icon.show()交互设计 右键菜单快速操作双击恢复窗口气泡消息提示 源码下载 import sys import time from datetime import datetime, timedelta import json import matplotlib.pyplot as plt from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QWidget, QTableWidget, QTableWidgetItem, QSystemTrayIcon, QMenu, QAction, QMessageBox, QTabWidget, QHeaderView,QLabel) from PyQt5.QtCore import QTimer, Qt from PyQt5.QtGui import QIcon, QFont, QColor import psutil import platform import os import numpy as np from matplotlib import cm from matplotlib.font_manager import FontProperties# 设置matplotlib支持中文显示 plt.rcParams[font.sans-serif] [Microsoft YaHei] # 使用微软雅黑 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号class AppUsageTracker(QMainWindow):def __init__(self):super().__init__()# 初始化数据self.app_data {}self.current_app Noneself.last_update_time time.time()self.data_dir app_usage_dataself.data_file os.path.join(self.data_dir, current_usage.json)# 创建数据目录os.makedirs(self.data_dir, exist_okTrue)# 加载历史数据self.load_data()# 初始化UIself.init_ui()# 设置系统托盘self.init_system_tray()# 设置定时器self.timer QTimer()self.timer.timeout.connect(self.update_app_usage)self.timer.start(1000) # 每秒更新一次# 每周数据定时保存self.weekly_save_timer QTimer()self.weekly_save_timer.timeout.connect(self.save_weekly_data)self.weekly_save_timer.start(3600000) # 每小时检查一次def init_ui(self):初始化用户界面self.setWindowTitle( 应用使用时长统计)self.setWindowIcon(QIcon(self.get_emoji_icon()))self.setGeometry(100, 100, 1200, 800) # 增大窗口尺寸# 主布局main_widget QWidget()self.setCentralWidget(main_widget)layout QVBoxLayout(main_widget)# 创建标签页self.tabs QTabWidget()self.tabs.currentChanged.connect(self.on_tab_changed)layout.addWidget(self.tabs)# 初始化各标签页self.init_realtime_tab()self.init_bar_chart_tab()self.init_pie_chart_tab()self.init_weekly_chart_tab() # 修改为周统计图表页# 添加工具栏self.init_toolbar()def on_tab_changed(self, index):标签页切换时自动刷新图表if index 1: # 使用时长排行标签页self.update_bar_chart()elif index 2: # 使用时长占比标签页self.update_pie_chart()elif index 3: # 周统计数据标签页self.update_weekly_chart()def init_realtime_tab(self):初始化实时数据标签页self.realtime_tab QWidget()self.tabs.addTab(self.realtime_tab, ⏱️ 实时数据)layout QVBoxLayout(self.realtime_tab)# 添加标题title_label QLabel(应用使用时长实时统计)title_label.setFont(QFont(Microsoft YaHei, 12, QFont.Bold))title_label.setAlignment(Qt.AlignCenter)title_label.setStyleSheet(padding: 10px;)layout.addWidget(title_label)# 创建表格self.table QTableWidget()self.table.setColumnCount(3)self.table.setHorizontalHeaderLabels([排名, 应用名称, 使用时长])# 设置表格样式self.table.setStyleSheet(QTableWidget { border: 1px solid #e0e0e0; }QTableWidget::item { padding: 5px; }QHeaderView::section { background-color: #f0f0f0; padding: 5px; })self.table.setColumnWidth(0, 60)self.table.setColumnWidth(1, 300)self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.Stretch)self.table.setEditTriggers(QTableWidget.NoEditTriggers)self.table.setSortingEnabled(False)self.table.setAlternatingRowColors(True)layout.addWidget(self.table)def init_bar_chart_tab(self):初始化条形图标签页self.bar_chart_tab QWidget()self.tabs.addTab(self.bar_chart_tab, 使用时长排行)layout QVBoxLayout(self.bar_chart_tab)# 添加标题title_label QLabel(应用使用时长排行榜)title_label.setFont(QFont(Microsoft YaHei, 12, QFont.Bold))title_label.setAlignment(Qt.AlignCenter)title_label.setStyleSheet(padding: 10px;)layout.addWidget(title_label)# 创建图表self.bar_figure plt.figure(figsize(10, 6), dpi100, facecolorwhite)self.bar_canvas FigureCanvas(self.bar_figure)layout.addWidget(self.bar_canvas)def init_pie_chart_tab(self):初始化饼图标签页self.pie_chart_tab QWidget()self.tabs.addTab(self.pie_chart_tab, 使用时长占比)layout QVBoxLayout(self.pie_chart_tab)# 添加标题title_label QLabel(应用使用时长占比)title_label.setFont(QFont(Microsoft YaHei, 12, QFont.Bold))title_label.setAlignment(Qt.AlignCenter)title_label.setStyleSheet(padding: 10px;)layout.addWidget(title_label)# 创建图表self.pie_figure plt.figure(figsize(10, 6), dpi100, facecolorwhite)self.pie_canvas FigureCanvas(self.pie_figure)layout.addWidget(self.pie_canvas)def init_weekly_chart_tab(self):初始化周统计图表标签页self.weekly_chart_tab QWidget()self.tabs.addTab(self.weekly_chart_tab, 周使用趋势)layout QVBoxLayout(self.weekly_chart_tab)# 添加标题title_label QLabel(近七日应用使用时长趋势)title_label.setFont(QFont(Microsoft YaHei, 12, QFont.Bold))title_label.setAlignment(Qt.AlignCenter)title_label.setStyleSheet(padding: 10px;)layout.addWidget(title_label)# 创建图表self.weekly_figure plt.figure(figsize(12, 7), dpi100, facecolorwhite)self.weekly_canvas FigureCanvas(self.weekly_figure)layout.addWidget(self.weekly_canvas)def init_toolbar(self):初始化工具栏self.refresh_button QAction( 刷新图表, self)self.refresh_button.triggered.connect(self.update_all_charts)self.toolbar self.addToolBar(工具栏)self.toolbar.addAction(self.refresh_button)def init_system_tray(self):初始化系统托盘self.tray_icon QSystemTrayIcon(self)self.tray_icon.setIcon(QIcon(self.get_emoji_icon(⏱️)))tray_menu QMenu()show_action QAction( 显示窗口, self)show_action.triggered.connect(self.show)tray_menu.addAction(show_action)exit_action QAction( 退出, self)exit_action.triggered.connect(self.close_app)tray_menu.addAction(exit_action)self.tray_icon.setContextMenu(tray_menu)self.tray_icon.show()self.tray_icon.activated.connect(self.tray_icon_clicked)def tray_icon_clicked(self, reason):托盘图标点击事件处理if reason QSystemTrayIcon.DoubleClick:self.show()self.activateWindow()def close_app(self):退出应用程序self.save_data()self.tray_icon.hide()QApplication.quit()def closeEvent(self, event):重写关闭事件最小化到托盘event.ignore()self.hide()self.tray_icon.showMessage(应用使用时长统计,程序已最小化到系统托盘,QSystemTrayIcon.Information,2000)def get_emoji_icon(self, emoji):将emoji转换为图标return emojidef get_current_app(self):获取当前活动窗口的应用try:current_app Unknownif platform.system() Windows:import win32guiimport win32processwindow win32gui.GetForegroundWindow()_, pid win32process.GetWindowThreadProcessId(window)try:process psutil.Process(pid)current_app process.name()current_app os.path.splitext(current_app)[0]except (psutil.NoSuchProcess, psutil.AccessDenied):current_app Unknownelif platform.system() Darwin:from AppKit import NSWorkspacecurrent_app NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()else: # Linuximport subprocesstry:window_id subprocess.check_output([xdotool, getactivewindow]).decode().strip()pid subprocess.check_output([xdotool, getwindowpid, window_id]).decode().strip()process psutil.Process(int(pid))current_app process.name()current_app os.path.splitext(current_app)[0]except:current_app Unknown# 清理应用名称for suffix in [.exe, .bin, .app]:if current_app.endswith(suffix):current_app current_app[:-len(suffix)]return current_appexcept Exception as e:print(f获取应用名称出错: {e})return Unknowndef update_app_usage(self):更新应用使用时长current_app self.get_current_app()current_time time.time()time_elapsed current_time - self.last_update_timeif self.current_app is not None:if self.current_app in self.app_data:self.app_data[self.current_app] time_elapsedelse:self.app_data[self.current_app] time_elapsedself.current_app current_appself.last_update_time current_timeself.update_table()if current_time % 3600 1: # 大约每小时保存一次self.save_data()def update_table(self):更新表格数据sorted_data sorted(self.app_data.items(), keylambda x: x[1], reverseTrue)self.table.setRowCount(len(sorted_data))for row, (app, seconds) in enumerate(sorted_data):# 排名rank_item QTableWidgetItem(str(row 1))rank_item.setTextAlignment(Qt.AlignCenter)# 应用名称app_item QTableWidgetItem(app)# 使用时长time_item QTableWidgetItem(self.format_time(seconds))time_item.setTextAlignment(Qt.AlignRight)# 设置数据for item in [rank_item, app_item, time_item]:item.setData(Qt.UserRole, seconds)self.table.setItem(row, 0, rank_item)self.table.setItem(row, 1, app_item)self.table.setItem(row, 2, time_item)# 高亮显示当前运行应用if app self.current_app:for col in range(3):item self.table.item(row, col)item.setBackground(QColor(220, 240, 255))item.setFont(QFont(Microsoft YaHei, 9, QFont.Bold))# 设置前三名样式if row 3:for col in range(3):item self.table.item(row, col)item.setBackground(QColor(255, 240, 200))item.setFont(QFont(Microsoft YaHei, 9, QFont.Bold))def update_all_charts(self):更新所有图表self.update_bar_chart()self.update_pie_chart()self.update_weekly_chart()def update_bar_chart(self):更新条形图self.bar_figure.clear()ax self.bar_figure.add_subplot(111)if not self.app_data:ax.text(0.5, 0.5, 暂无数据, hacenter, vacenter, fontsize12)self.bar_canvas.draw()return# 准备数据sorted_data sorted(self.app_data.items(), keylambda x: x[1], reverseTrue)apps [app[:15] ... if len(app) 15 else app for app, _ in sorted_data]times [secs / 3600 for _, secs in sorted_data]# 创建条形图colors cm.viridis(np.linspace(0.2, 0.8, len(apps)))bars ax.barh(np.arange(len(apps)), times, colorcolors, edgecolornone)# 设置标签ax.set_yticks(np.arange(len(apps)))ax.set_yticklabels(apps)# 添加数据标签for bar in bars:width bar.get_width()ax.text(width, bar.get_y() bar.get_height()/2,f {width:.1f}h, vacenter, haleft, fontsize9)# 美化图表ax.set_xlabel(使用时长 (小时), fontsize11)ax.set_title(应用使用时长统计, fontsize13, pad15)ax.spines[top].set_visible(False)ax.spines[right].set_visible(False)ax.grid(True, axisx, color#e0e0e0, linestyle--, alpha0.7)ax.invert_yaxis()self.bar_figure.tight_layout()self.bar_canvas.draw()def update_pie_chart(self):更新饼图self.pie_figure.clear()ax self.pie_figure.add_subplot(111)if not self.app_data:ax.text(0.5, 0.5, 暂无数据, hacenter, vacenter, fontsize12)self.pie_canvas.draw()return# 准备数据sorted_data sorted(self.app_data.items(), keylambda x: x[1], reverseTrue)total_time sum(secs for _, secs in sorted_data)app_percentages [(app, (secs/total_time)*100) for app, secs in sorted_data]# 分离主要应用和其他应用main_apps [item for item in app_percentages if item[1] 5]other_apps [item for item in app_percentages if item[1] 5]other_time sum(secs for _, secs in sorted_data if (secs/total_time)*100 5)if other_apps:labels [app for app, _ in main_apps] [其他]sizes [secs for _, secs in sorted_data if (secs/total_time)*100 5] [other_time]else:labels [app for app, _ in main_apps]sizes [secs for _, secs in sorted_data]# 限制标签长度labels [label[:12] ... if len(label) 12 else label for label in labels]percentages [(size/total_time)*100 for size in sizes]# 创建饼图colors cm.plasma(np.linspace(0.2, 0.8, len(labels)))font FontProperties(size9)wedges, texts, autotexts ax.pie(sizes,labelslabels,colorscolors,autopctlambda p: f{p:.1f}% if p 5 else ,startangle90,wedgeprops{linewidth: 1, edgecolor: white},textprops{fontproperties: font},pctdistance0.85,labeldistance1.05)# 添加中心总时长ax.text(0, 0, f总时长\n{self.format_time(total_time)}, hacenter, vacenter, fontsize11)# 添加图例和标题ax.set_title(应用使用时长占比 (≥5%显示), fontsize13, pad15)legend_labels [f{label} ({p:.1f}%) for label, p in zip(labels, percentages)]ax.legend(wedges, legend_labels,title应用列表,loccenter left,bbox_to_anchor(1, 0, 0.5, 1),frameonFalse,propfont)self.pie_figure.tight_layout()self.pie_canvas.draw()def update_weekly_chart(self):更新周统计柱状图self.weekly_figure.clear()ax self.weekly_figure.add_subplot(111)# 获取最近7天的日期today datetime.now().date()dates [(today - timedelta(daysi)).strftime(%m-%d) for i in range(6, -1, -1)]full_dates [(today - timedelta(daysi)).strftime(%Y-%m-%d) for i in range(6, -1, -1)]# 收集所有应用名称all_apps set()weekly_data {}for date in full_dates:daily_data self.load_daily_data(date)if daily_data:weekly_data[date] daily_dataall_apps.update(daily_data.keys())if not all_apps:ax.text(0.5, 0.5, 暂无周数据, hacenter, vacenter, fontsize12)self.weekly_canvas.draw()return# 选择前5个最常用的应用app_total_time {app: 0 for app in all_apps}for date in full_dates:if date in weekly_data:for app, secs in weekly_data[date].items():app_total_time[app] secstop_apps sorted(app_total_time.items(), keylambda x: x[1], reverseTrue)[:5]top_apps [app for app, _ in top_apps]# 准备柱状图数据bar_width 0.15x np.arange(len(dates))# 创建颜色映射colors cm.viridis(np.linspace(0.2, 0.8, len(top_apps)))# 绘制每个应用的柱状图for i, app in enumerate(top_apps):app_times []for date in full_dates:if date in weekly_data and app in weekly_data[date]:app_times.append(weekly_data[date][app] / 3600) # 转换为小时else:app_times.append(0)ax.bar(x i*bar_width, app_times, bar_width, labelapp[:12] ... if len(app) 12 else app,colorcolors[i])# 设置x轴标签ax.set_xticks(x bar_width * (len(top_apps)-1)/2)ax.set_xticklabels(dates)# 美化图表ax.set_xlabel(日期, fontsize11)ax.set_ylabel(使用时长 (小时), fontsize11)ax.set_title(近七日应用使用时长趋势 (Top 5应用), fontsize13, pad15)ax.legend(bbox_to_anchor(1.05, 1), locupper left)ax.grid(True, axisy, color#e0e0e0, linestyle--, alpha0.7)self.weekly_figure.tight_layout()self.weekly_canvas.draw()def format_time(self, seconds):将秒数格式化为 HH:MM:SShours int(seconds // 3600)minutes int((seconds % 3600) // 60)seconds int(seconds % 60)return f{hours:02d}:{minutes:02d}:{seconds:02d}def load_data(self):加载保存的数据try:if os.path.exists(self.data_file):with open(self.data_file, r, encodingutf-8) as f:self.app_data {k: float(v) for k, v in json.load(f).items()}except (FileNotFoundError, json.JSONDecodeError, ValueError) as e:print(f加载数据出错: {e})self.app_data {}def save_data(self):保存当前数据try:with open(self.data_file, w, encodingutf-8) as f:json.dump(self.app_data, f, ensure_asciiFalse, indent2)except Exception as e:print(f保存数据出错: {e})def load_daily_data(self, date):加载指定日期的数据filename os.path.join(self.data_dir, fapp_usage_{date}.json)try:if os.path.exists(filename):with open(filename, r, encodingutf-8) as f:return json.load(f)except (FileNotFoundError, json.JSONDecodeError) as e:print(f加载每日数据出错: {e})return Nonedef save_weekly_data(self):每周数据保存today datetime.now().date().strftime(%Y-%m-%d)filename os.path.join(self.data_dir, fapp_usage_{today}.json)try:with open(filename, w, encodingutf-8) as f:json.dump(self.app_data, f, ensure_asciiFalse, indent2)except Exception as e:print(f保存每周数据出错: {e})self.app_data {}self.current_app self.get_current_app()self.last_update_time time.time()if __name__ __main__:app QApplication(sys.argv)app.setApplicationName(应用使用时长统计)app.setApplicationDisplayName( 应用使用时长统计)tracker AppUsageTracker()tracker.show()sys.exit(app.exec_())## 深度优化建议### 性能提升方向1. **数据压缩**对长期存储的JSON数据进行gzip压缩 2. **增量更新**改用SQLite替代JSON文件存储 3. **采样优化**动态调整监控频率活跃时高频闲置时低频### 功能扩展![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fdaac986aa20466b90e19ba6cc70a781.png)### 用户体验改进- 添加主题切换功能 - 支持导出CSV/PDF报告 - 增加数据筛选功能## 总结与展望这款应用时长统计工具通过1. **精准监控**秒级采集精度 2. **直观可视化**专业级图表呈现 3. **无感运行**完善的托盘管理 4. **数据持久化**双重备份机制实现了对数字生活习惯的全方位分析。特别适合- 自由职业者时间管理 - 家长监控儿童设备使用 - 程序员分析开发效率**未来演进路线**- 移动端配套应用 - 浏览器插件集成 - AI使用建议功能------ **版权声明**本文代码采用MIT开源协议转载请注明出处。如需商业使用请联系作者授权。**互动区**你的数字生活时间分配合理吗欢迎在评论区分享你的使用体验和改进建议
http://www.w-s-a.com/news/987698/

相关文章:

  • 网站多久才会被收录服务器租用泰海
  • 电商网站建设合同模板临汾推广型网站建设
  • 天猫商务网站建设目的长春网站设计
  • 公司网站建设会议纪要昆山高端网站建设机构
  • 做消费网站流程深圳网站设计价格
  • 做电影网站怎么接广告中国最新军事新闻视频
  • 网站推广设计做哪些设置自动删除的wordpress
  • 东莞东坑网站设计专业网站制作设
  • 网站怎么做现场直播视频成都科技网站建设找
  • 个人网页设计步骤网站没有内容 能做优化吗
  • 专业网站建设公司招聘网站排行榜
  • 网站建设规范方法企业解决方案架构
  • ae做网站导航wordpress门户
  • 重庆市网站备案材料云南做网站
  • 网页设计模板网站免费珠海视窗网
  • 茂名模板建站定制WordPress注册不提示
  • 陕西营销型手机网站建设深圳制作网站服务
  • 受欢迎的锦州网站建设Wordpress 图片左右滑动
  • 湖南优化网站建设线上网站建设需求
  • 建什么类型的网站访问量比较大哪些外包公司比较好
  • php网站地图外贸建站哪家强外贸网站怎么做
  • 宁波五金网站建设中国建筑网官网投诉查询
  • 哪个网站注册域名便宜免费流程图制作网站
  • 潍坊做网站南宁网站seo优化公司
  • 网站建设的基本技术步骤无网站营销
  • 我国旅游网站的建设网站开发 混合式 数据库
  • 淘宝客网站域名家居网站开发项目计划书
  • 网站打不开显示asp苏州注册公司需要多少钱
  • 凡科建站登录官网wordpress主题有什么用
  • 西安双语网站建设怎么做网页动图