Python+Qt实现智能应用时长统计工具

 更新时间:2025年06月19日 08:10:46   作者:创客白泽  
在数字化生活日益普及的今天,我们每天与各种应用程序的交互时间越来越长,但你是否真正了解自己的数字生活习惯,下面我们就来使用Python和Qt打造智能应用时长统计工具吧

概述:数字时代的时间管理者

在数字化生活日益普及的今天,我们每天与各种应用程序的交互时间越来越长。但你是否真正了解自己的数字生活习惯?哪些应用占用了你最多的时间?时间都花在了哪里?

今天我将介绍一款自主研发的应用时长统计工具,它能够:

  • 实时监控应用使用情况
  • 可视化展示时间分配
  • 分析每周使用趋势
  • 最小化到系统托盘后台运行

这款工具采用Python+Qt开发,结合matplotlib实现专业级数据可视化,是程序员和普通用户都能轻松使用的效率工具。

功能全景图

核心功能矩阵

功能模块技术实现数据维度
实时监控psutil+win32api跨平台采集秒级精度
数据持久化JSON序列化+按日期存储历史数据可追溯
可视化分析Matplotlib+Qt5嵌入式图表多维数据呈现
系统托盘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 win32gui
            window = 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(days=i) 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(), key=lambda x: x[1], reverse=True)[: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, label=app)
    
    # 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 = None
        self.last_update_time = time.time()
        self.data_dir = "app_usage_data"
        self.data_file = os.path.join(self.data_dir, "current_usage.json")
        
        # 创建数据目录
        os.makedirs(self.data_dir, exist_ok=True)
        
        # 加载历史数据
        self.load_data()
        
        # 初始化UI
        self.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), dpi=100, facecolor='white')
        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), dpi=100, facecolor='white')
        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), dpi=100, facecolor='white')
        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 emoji
        
    def get_current_app(self):
        """获取当前活动窗口的应用"""
        try:
            current_app = "Unknown"
            
            if platform.system() == "Windows":
                import win32gui
                import win32process
                
                window = 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 = "Unknown"
                    
            elif platform.system() == "Darwin":
                from AppKit import NSWorkspace
                current_app = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
                
            else:  # Linux
                import subprocess
                try:
                    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_app
            
        except Exception as e:
            print(f"获取应用名称出错: {e}")
            return "Unknown"
        
    def update_app_usage(self):
        """更新应用使用时长"""
        current_app = self.get_current_app()
        current_time = time.time()
        time_elapsed = current_time - self.last_update_time
        
        if self.current_app is not None:
            if self.current_app in self.app_data:
                self.app_data[self.current_app] += time_elapsed
            else:
                self.app_data[self.current_app] = time_elapsed
        
        self.current_app = current_app
        self.last_update_time = current_time
        
        self.update_table()
        
        if current_time % 3600 < 1:  # 大约每小时保存一次
            self.save_data()
            
    def update_table(self):
        """更新表格数据"""
        sorted_data = sorted(self.app_data.items(), key=lambda x: x[1], reverse=True)
        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, "暂无数据", ha='center', va='center', fontsize=12)
            self.bar_canvas.draw()
            return
        
        # 准备数据
        sorted_data = sorted(self.app_data.items(), key=lambda x: x[1], reverse=True)
        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, color=colors, edgecolor='none')
        
        # 设置标签
        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', va='center', ha='left', fontsize=9)
        
        # 美化图表
        ax.set_xlabel('使用时长 (小时)', fontsize=11)
        ax.set_title('应用使用时长统计', fontsize=13, pad=15)
        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        ax.grid(True, axis='x', color='#e0e0e0', linestyle='--', alpha=0.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, "暂无数据", ha='center', va='center', fontsize=12)
            self.pie_canvas.draw()
            return
        
        # 准备数据
        sorted_data = sorted(self.app_data.items(), key=lambda x: x[1], reverse=True)
        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(size=9)
        
        wedges, texts, autotexts = ax.pie(
            sizes,
            labels=labels,
            colors=colors,
            autopct=lambda p: f'{p:.1f}%' if p >= 5 else '',
            startangle=90,
            wedgeprops={'linewidth': 1, 'edgecolor': 'white'},
            textprops={'fontproperties': font},
            pctdistance=0.85,
            labeldistance=1.05
        )
        
        # 添加中心总时长
        ax.text(0, 0, f"总时长\n{self.format_time(total_time)}", 
                ha='center', va='center', fontsize=11)
        
        # 添加图例和标题
        ax.set_title('应用使用时长占比 (≥5%显示)', fontsize=13, pad=15)
        legend_labels = [f"{label} ({p:.1f}%)" for label, p in zip(labels, percentages)]
        ax.legend(wedges, legend_labels,
                 title="应用列表",
                 loc="center left",
                 bbox_to_anchor=(1, 0, 0.5, 1),
                 frameon=False,
                 prop=font)
        
        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(days=i)).strftime("%m-%d") for i in range(6, -1, -1)]
        full_dates = [(today - timedelta(days=i)).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_data
                all_apps.update(daily_data.keys())
        
        if not all_apps:
            ax.text(0.5, 0.5, "暂无周数据", ha='center', va='center', fontsize=12)
            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] += secs
        
        top_apps = sorted(app_total_time.items(), key=lambda x: x[1], reverse=True)[:5]
        top_apps = [app for app, _ in top_apps]
        
        # 准备柱状图数据
        bar_width = 0.15
        x = 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, 
                  label=app[:12] + '...' if len(app) > 12 else app,
                  color=colors[i])
        
        # 设置x轴标签
        ax.set_xticks(x + bar_width * (len(top_apps)-1)/2)
        ax.set_xticklabels(dates)
        
        # 美化图表
        ax.set_xlabel('日期', fontsize=11)
        ax.set_ylabel('使用时长 (小时)', fontsize=11)
        ax.set_title('近七日应用使用时长趋势 (Top 5应用)', fontsize=13, pad=15)
        ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
        ax.grid(True, axis='y', color='#e0e0e0', linestyle='--', alpha=0.7)
        
        self.weekly_figure.tight_layout()
        self.weekly_canvas.draw()
        
    def format_time(self, seconds):
        """将秒数格式化为 HH:MM:SS"""
        hours = 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", encoding='utf-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", encoding='utf-8') as f:
                json.dump(self.app_data, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存数据出错: {e}")
            
    def load_daily_data(self, date):
        """加载指定日期的数据"""
        filename = os.path.join(self.data_dir, f"app_usage_{date}.json")
        try:
            if os.path.exists(filename):
                with open(filename, "r", encoding='utf-8') as f:
                    return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError) as e:
            print(f"加载每日数据出错: {e}")
        return None
            
    def save_weekly_data(self):
        """每周数据保存"""
        today = datetime.now().date().strftime("%Y-%m-%d")
        filename = os.path.join(self.data_dir, f"app_usage_{today}.json")
        
        try:
            with open(filename, "w", encoding='utf-8') as f:
                json.dump(self.app_data, f, ensure_ascii=False, indent=2)
        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. **采样优化**:动态调整监控频率(活跃时高频,闲置时低频)

功能扩展

用户体验改进

- 添加主题切换功能

- 支持导出CSV/PDF报告

- 增加数据筛选功能

总结与展望

这款应用时长统计工具通过:

1. **精准监控**:秒级采集精度

2. **直观可视化**:专业级图表呈现

3. **无感运行**:完善的托盘管理

4. **数据持久化**:双重备份机制

实现了对数字生活习惯的全方位分析。特别适合:

- 自由职业者时间管理
- 家长监控儿童设备使用
- 程序员分析开发效率

**未来演进路线**:

- 移动端配套应用
- 浏览器插件集成
- AI使用建议功能

以上就是Python+Qt实现智能应用时长统计工具的详细内容,更多关于Python统计应用时长的资料请关注脚本之家其它相关文章!

相关文章

  • Python Excel实现自动添加编号

    Python Excel实现自动添加编号

    这篇文章主要为大家详细介绍了如何使用Python在Excel中实现自动添加编号效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-03-03
  • Python分支语句常见的使用方法

    Python分支语句常见的使用方法

    这篇文章主要介绍了Python分支语句常见的使用方法,Python分支语句,也称为选择语句,体现了程序的选择结构,即对应不同的场景,选择不同的处理方式,具体常见的用法需要的朋友可参考下面文章内容
    2022-06-06
  • 彻底理解Python list切片原理

    彻底理解Python list切片原理

    本篇文章主要介绍了Python list切片原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • 一文带你精通Python中*args和**kwargs的应用技巧

    一文带你精通Python中*args和**kwargs的应用技巧

    如果能在Python中创建适应不同场景的函数,而无需每次都重写它们,会使得操作简洁方便,这就是*args和**kwargs的魔力所在,下面我们就来看看它们的具体一些应用技巧吧
    2024-03-03
  • 利用Python创建位置生成器的示例详解

    利用Python创建位置生成器的示例详解

    在这篇文章中,我们将探索如何利用Python在美国各地城市的地图数据和公共电动自行车订阅源上训练一个快速生成的对抗网络(GAN)模型,需要的可以参考一下
    2022-06-06
  • PyQt信号和槽机制的具体使用

    PyQt信号和槽机制的具体使用

    信号和槽机制是一种通信机制,在PyQt中,信号是一种特殊的函数,它可以传递任何类型的数据,而槽则是一种接收信号的函数,本文就介绍了PyQt信号和槽机制的具体使用,感兴趣的可以了解一下
    2023-08-08
  • 关于python3的ThreadPoolExecutor线程池大小设置

    关于python3的ThreadPoolExecutor线程池大小设置

    这篇文章主要介绍了关于python3的ThreadPoolExecutor线程池大小设置,线程池的理想大小取决于被提交任务的类型以及所部署系统的特性,需要的朋友可以参考下
    2023-04-04
  • django ajax json的实例代码

    django ajax json的实例代码

    今天就为大家分享一篇django ajax json的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • python编写简单爬虫资料汇总

    python编写简单爬虫资料汇总

    本文给大家汇总介绍了下几种使用Python编写简单爬虫的方法和代码,非常的不错,这里分享给大家,希望大家能够喜欢。
    2016-03-03
  • Python软件包安装的三种常见方法

    Python软件包安装的三种常见方法

    python拥有非常丰富的扩展包,下面这篇文章主要给大家介绍了关于Python软件包安装的三种常见方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07

最新评论