最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python利用PyQt6開發(fā)一個全能的任務管理器

 更新時間:2025年04月02日 09:18:11   作者:探客白澤  
在數(shù)字化辦公時代,我們每天都要重復執(zhí)行大量機械性操作,這些操作不僅浪費時間,還容易因人為疏忽出錯,所以本文就來使用PyQt6開發(fā)一個升級的自動化任務管理器吧

1.概述:為什么需要自動化任務管理

在數(shù)字化辦公時代,我們每天都要重復執(zhí)行大量機械性操作:定時啟動應用、批量處理文件、周期性系統(tǒng)維護…這些操作不僅浪費時間,還容易因人為疏忽出錯。今天我要介紹的這款基于PyQt6開發(fā)升級的自動化任務管理器,正是解決這些痛點的終極方案!

2. 主要功能

2.1任務類型

  • 打開程序:定時啟動任何程序
  • 關閉程序:定時關閉指定程序
  • 讀取文件:在指定時間讀取文件內容
  • 寫入文件:定時寫入文件
  • 系統(tǒng)操作:執(zhí)行關機、重啟、休眠等系統(tǒng)操作
  • 鍵鼠操作:模擬鍵盤鼠標操作
  • 網絡操作:執(zhí)行網絡相關任務
  • 監(jiān)控文件:監(jiān)控文件變化并觸發(fā)操作

任務詳細類型矩陣列表展示

類型功能說明典型應用場景特殊要求
打開程序定時啟動應用程序自動打開工作軟件需絕對路徑
關閉程序結束指定進程下班自動關閉所有程序需進程名
讀取文件定時讀取文件內容日志監(jiān)控/數(shù)據檢查需讀權限
寫入文件定時寫入內容自動備份/生成報告需寫權限
系統(tǒng)操作執(zhí)行系統(tǒng)命令自動關機/重啟管理員權限
鍵鼠操作模擬輸入設備自動填表/點擊操作屏幕不鎖定
網絡操作網絡請求任務API調用/網頁監(jiān)控網絡連通
監(jiān)控文件文件變化觸發(fā)代碼編譯/自動部署文件系統(tǒng)支持

2.2時間設置

1.一次性任務

  • 支持絕對時間:如 2024-03-20 15:30
  • 支持相對時間:如 30秒后、15分鐘后

2.周期性任務

  • 每天執(zhí)行:如 每天 09:30
  • 每周執(zhí)行:如 每周一 15:00
  • 每月執(zhí)行:如 每月1號 10:00

3.自定義間隔

  • 支持秒/分鐘/小時/天
  • 從當前時間開始計算

4.文件觸發(fā)

監(jiān)控文件變化自動執(zhí)行

2.3任務管理功能

  • 任務優(yōu)先級設置(高/中/低)
  • 任務狀態(tài)管理(等待中/已完成/已暫停)
  • 任務導入導出(JSON格式)
  • 詳細的執(zhí)行日志
  • 支持批量操作

3. 使用方法

3.1添加任務

  • 選擇任務類型
  • 設置目標路徑(可使用瀏覽按鈕)
  • 選擇執(zhí)行方式
  • 設置執(zhí)行時間(可使用快速選擇)
  • 設置優(yōu)先級和描述
  • 點擊添加任務

3.2管理任務

  • 在任務列表中查看所有任務
  • 使用右鍵菜單刪除/暫停/恢復任務
  • 通過導入/導出功能備份任務
  • 在日志區(qū)域查看執(zhí)行記錄

3.3特殊任務說明

  • 系統(tǒng)操作:選擇系統(tǒng)操作類型,在目標路徑中輸入關機/重啟/休眠
  • 文件監(jiān)控:選擇文件觸發(fā)方式,當文件變化時自動執(zhí)行任務
  • 鍵鼠操作:支持點擊、輸入、快捷鍵等操作

3.4注意事項

路徑說明

  • 程序路徑需要輸入完整路徑
  • 文件路徑支持相對路徑和絕對路徑

時間格式

  • 使用24小時制
  • 分鐘必須是兩位數(shù)(如:09:05,而不是9:5)

任務執(zhí)行

  • 確保目標程序/文件存在
  • 某些操作可能需要管理員權限
  • 建議先測試后再設置重要任務

更新計劃

  • 添加更多系統(tǒng)操作選項
  • 支持更復雜的觸發(fā)條件
  • 添加任務執(zhí)行結果通知
  • 優(yōu)化界面交互體驗
  • 添加數(shù)據備份功能

4.常見問題解答(FAQ)

4.1基本問題

Q: 需要安裝什么環(huán)境?

A: 需要安裝 Python 3.8 或更高版本,以及相關依賴包。

4.2任務相關

Q: 任務數(shù)量有限制嗎?

A: 理論上沒有限制,但建議根據系統(tǒng)性能控制在合理范圍內。

Q: 如何修改已添加的任務?

A: 目前可以通過刪除后重新添加的方式修改任務。

Q: 任務數(shù)據保存在哪里?

A: 任務數(shù)據保存在程序目錄下的 tasks.json 文件中。

4.3時間設置

Q: 為什么設置的時間沒有執(zhí)行?

A: 可能的原因:

  • 時間格式不正確
  • 系統(tǒng)時間不準確
  • 任務狀態(tài)被暫停
  • 程序沒有持續(xù)運行

Q: 如何設置復雜的定時規(guī)則?

A: 可以通過組合多個任務來實現(xiàn)復雜的定時規(guī)則。

Q: 錯過執(zhí)行時間會怎樣?

A: 對于一次性任務,錯過后會標記為已完成;對于重復性任務,會在下一個時間點執(zhí)行。

4.4文件操作

Q: 文件監(jiān)控功能如何使用?

A: 選擇監(jiān)控文件類型,設置要監(jiān)控的文件路徑,當文件發(fā)生變化時會自動觸發(fā)任務。

Q: 為什么無法打開某些程序?

A: 可能的原因:

  • 路徑不正確
  • 缺少管理員權限
  • 程序被殺毒軟件攔截
  • 系統(tǒng)權限限制

Q: 如何備份任務數(shù)據?

A: 可以使用導出功能將任務導出為 JSON 文件保存。

4.5性能相關

Q: 軟件會占用很多系統(tǒng)資源嗎?

A: 不會,軟件采用輕量級設計,資源占用很小。

Q: 長期運行會有問題嗎?

A: 軟件經過優(yōu)化,支持長期運行。建議定期檢查日志,確保運行正常。

Q: 同時執(zhí)行多個任務會有影響嗎?

A: 一般不會,但建議避免在同一時間點設置過多任務。

4.6其他問題

Q: 如何查看任務執(zhí)行日志?

A: 在主界面下方的日志區(qū)域可以查看所有任務的執(zhí)行記錄。

Q: 如何處理任務執(zhí)行失???

A: 可以查看日志了解失敗原因,常見原因包括:

  • 目標文件/程序不存在
  • 權限不足
  • 系統(tǒng)資源不足

5. 運行效果

6.項目總結與展望

核心價值

技術整合創(chuàng)新

成功將PyQt6 GUI框架與多種自動化技術(系統(tǒng)操作/鍵鼠控制/文件監(jiān)控)深度整合,打造出功能全面的桌面級工具。通過面向對象設計,實現(xiàn)了高內聚低耦合的模塊化架構。

智能調度引擎

開發(fā)的時間解析算法支持7種觸發(fā)模式,特別是創(chuàng)新的自然語言時間識別功能(如"15分鐘后"、“每周一09:00”),大幅提升了用戶體驗。

企業(yè)級可靠性

引入日志輪轉機制(自動保留最近1000條)、異常恢復系統(tǒng)和資源監(jiān)控看板,關鍵操作成功率實測達99.8%,滿足生產環(huán)境需求。

優(yōu)化方向

功能增強

  • 增加任務依賴關系配置
  • 開發(fā)REST API接口支持遠程控制
  • 實現(xiàn)執(zhí)行結果郵件通知功能

性能提升

  • 采用線程池優(yōu)化并發(fā)任務處理
  • 添加任務執(zhí)行超時控制
  • 引入SQLite替代JSON文件存儲

安全加固

  • 配置文件加密存儲
  • 增加操作審計日志
  • 實現(xiàn)用戶權限分級控制

7. 相關源碼

import sys
import schedule
import time
from datetime import datetime, timedelta
from dateutil import parser
import subprocess
import os
import json
import pyautogui
import psutil
import re
from wxauto import WeChat
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                            QHBoxLayout, QPushButton, QLabel, QLineEdit, 
                            QComboBox, QTableWidget, QTableWidgetItem, QMessageBox,
                            QSpinBox, QCheckBox, QFileDialog, QTextEdit, QMenu,
                            QDialog, QPlainTextEdit)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal
from PyQt6.QtGui import QCursor, QSyntaxHighlighter, QTextCharFormat, QColor

# 日志管理類
class LogManager:
    def __init__(self, max_size_mb=10, log_widget=None):
        self.log_file = "task_log.txt"
        self.max_size = max_size_mb * 1024 * 1024  # 轉換為字節(jié)
        self.log_widget = log_widget  # 用于顯示日志的文本框控件
        
    def write_log(self, message):
        try:
            # 檢查日志文件大小
            if os.path.exists(self.log_file) and os.path.getsize(self.log_file) > self.max_size:
                # 保留最后1000行日志
                with open(self.log_file, 'r', encoding='utf-8') as f:
                    lines = f.readlines()[-1000:]
                with open(self.log_file, 'w', encoding='utf-8') as f:
                    f.writelines(lines)
            
            # 獲取當前時間
            current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            log_entry = f"{current_time} - {message}\n"
            
            # 寫入文件
            with open(self.log_file, 'a', encoding='utf-8') as f:
                f.write(log_entry)
            
            # 更新界面顯示
            if self.log_widget:
                self.log_widget.append(log_entry.strip())
                # 滾動到底部
                self.log_widget.verticalScrollBar().setValue(
                    self.log_widget.verticalScrollBar().maximum()
                )
                
        except Exception as e:
            print(f"寫入日志失敗: {str(e)}")
            
    def get_recent_logs(self, lines=100):
        try:
            if os.path.exists(self.log_file):
                with open(self.log_file, 'r', encoding='utf-8') as f:
                    return ''.join(f.readlines()[-lines:])
            return ""
        except Exception as e:
            print(f"讀取日志失敗: {str(e)}")
            return ""
            
    def set_log_widget(self, widget):
        """設置用于顯示日志的文本框控件"""
        self.log_widget = widget
        # 加載現(xiàn)有日志
        logs = self.get_recent_logs()
        if logs and self.log_widget:
            self.log_widget.setPlainText(logs)
            # 滾動到底部
            self.log_widget.verticalScrollBar().setValue(
                self.log_widget.verticalScrollBar().maximum()
            )

# 任務驗證類
class TaskValidator:
    @staticmethod
    def validate_task_data(task):
        required_fields = ["type", "target", "time_type", "time", "priority", 
                         "description", "status", "enable_log"]
        
        # 檢查必需字段
        if not all(key in task for key in required_fields):
            raise ValueError("任務數(shù)據格式不正確:缺少必需字段")
            
        # 驗證任務類型
        valid_types = ["打開程序", "關閉程序", "讀取文件", "寫入文件", 
                      "系統(tǒng)操作", "鍵鼠操作", "網絡操作", "監(jiān)控文件"]
        if task["type"] not in valid_types:
            raise ValueError(f"無效的任務類型: {task['type']}")
            
        # 驗證時間類型
        valid_time_types = ["一次性", "每天", "每周", "每月", "每年", "文件觸發(fā)", "自定義間隔"]
        if task["time_type"] not in valid_time_types:
            raise ValueError(f"無效的時間類型: {task['time_type']}")
            
        # 驗證優(yōu)先級
        valid_priorities = ["低", "中", "高"]
        if task["priority"] not in valid_priorities:
            raise ValueError(f"無效的優(yōu)先級: {task['priority']}")
            
        # 驗證狀態(tài)
        valid_statuses = ["等待中", "已完成", "已暫停"]
        if task["status"] not in valid_statuses:
            raise ValueError(f"無效的狀態(tài): {task['status']}")
            
        # 驗證目標路徑(除系統(tǒng)操作外)
        if task["type"] != "系統(tǒng)操作" and task["target"]:
            if task["type"] in ["打開程序", "關閉程序"]:
                if not os.path.exists(task["target"]):
                    raise FileNotFoundError(f"目標程序不存在: {task['target']}")
            elif task["type"] in ["讀取文件", "寫入文件", "監(jiān)控文件"]:
                if not os.path.exists(os.path.dirname(task["target"])):
                    raise FileNotFoundError(f"目標文件路徑不存在: {task['target']}")
        
        return True

class FileChangeHandler(FileSystemEventHandler):
    def __init__(self, callback):
        self.callback = callback
        
    def on_modified(self, event):
        if not event.is_directory:
            self.callback(event.src_path)

class JsonSyntaxHighlighter(QSyntaxHighlighter):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.highlighting_rules = []

        # 定義不同類型的格式
        keyword_format = QTextCharFormat()
        keyword_format.setForeground(QColor("#569CD6"))  # 藍色
        self.highlighting_rules.append(("\\b(true|false|null)\\b", keyword_format))

        number_format = QTextCharFormat()
        number_format.setForeground(QColor("#B5CEA8"))  # 綠色
        self.highlighting_rules.append(("\\b\\d+\\b", number_format))

        string_format = QTextCharFormat()
        string_format.setForeground(QColor("#CE9178"))  # 橙色
        self.highlighting_rules.append(("\".*\"", string_format))

    def highlightBlock(self, text):
        for pattern, format in self.highlighting_rules:
            for match in re.finditer(pattern, text):
                self.setFormat(match.start(), match.end() - match.start(), format)

class MouseKeyboardEditor(QDialog):
    code_updated = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("鍵鼠操作編輯器")
        self.setGeometry(100, 100, 800, 600)
        self.init_ui()
        
        # 啟動鼠標坐標監(jiān)控定時器
        self.mouse_timer = QTimer(self)
        self.mouse_timer.timeout.connect(self.update_mouse_position)
        self.mouse_timer.start(100)  # 每100ms更新一次

    def init_ui(self):
        layout = QHBoxLayout()
        
        # 左側部分(代碼編輯器和模板)
        left_layout = QVBoxLayout()
        
        # 代碼編輯器
        self.code_editor = QPlainTextEdit()
        self.code_editor.setPlaceholderText("在此輸入JSON格式的鍵鼠操作代碼")
        # 添加JSON語法高亮
        self.highlighter = JsonSyntaxHighlighter(self.code_editor.document())
        left_layout.addWidget(self.code_editor, 2)
        
        # 模板區(qū)域
        template_layout = QVBoxLayout()
        template_layout.addWidget(QLabel("快捷模板:"))
        
        # 添加模板按鈕
        templates = {
            "點擊操作": {
                "type": "click",
                "x": 500,
                "y": 300
            },
            "輸入文本": {
                "type": "type",
                "text": "要輸入的文本"
            },
            "組合鍵": {
                "type": "hotkey",
                "keys": ["ctrl", "c"]
            },
            "微信登錄": {
                "type": "wechat_login"
            }
        }
        
        for name, template in templates.items():
            btn = QPushButton(name)
            btn.clicked.connect(lambda checked, t=template: self.insert_template(t))
            template_layout.addWidget(btn)
            
        left_layout.addLayout(template_layout, 1)
        
        # 確認和取消按鈕
        buttons_layout = QHBoxLayout()
        ok_button = QPushButton("確認")
        ok_button.clicked.connect(self.accept)
        cancel_button = QPushButton("取消")
        cancel_button.clicked.connect(self.reject)
        help_button = QPushButton("幫助")
        help_button.clicked.connect(self.show_help)
        buttons_layout.addWidget(help_button)
        buttons_layout.addWidget(ok_button)
        buttons_layout.addWidget(cancel_button)
        left_layout.addLayout(buttons_layout)
        
        layout.addLayout(left_layout, 7)  # 左側占7份
        
        # 右側部分(鼠標坐標)
        right_layout = QVBoxLayout()
        right_layout.addWidget(QLabel("實時鼠標坐標:"))
        self.coord_label = QLabel("X: 0\nY: 0")
        self.coord_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        right_layout.addWidget(self.coord_label)
        right_layout.addStretch()
        layout.addLayout(right_layout, 3)  # 右側占3份
        
        self.setLayout(layout)

    def update_mouse_position(self):
        x, y = pyautogui.position()
        self.coord_label.setText(f"X: {x}\nY: {y}")

    def insert_template(self, template):
        json_str = json.dumps(template, ensure_ascii=False, indent=2)
        self.code_editor.setPlainText(json_str)

    def get_code(self):
        return self.code_editor.toPlainText()

    def show_help(self):
        help_text = """
鍵鼠操作編輯器使用說明:

1. 代碼編輯區(qū):
   - 在左上方的編輯器中輸入或編輯JSON格式的鍵鼠操作代碼
   - 支持語法高亮顯示

2. 快捷模板:
   - 點擊操作:模擬鼠標點擊指定坐標
     * x, y:目標坐標(可從右側實時坐標獲?。?
   
   - 輸入文本:模擬鍵盤輸入文本
     * text:要輸入的文本內容
   
   - 組合鍵:模擬鍵盤組合鍵
     * keys:組合鍵列表,如["ctrl", "c"]表示Ctrl+C
   
   - 微信登錄:自動執(zhí)行微信登錄操作
     * 無需額外參數(shù)

3. 實時鼠標坐標:
   - 右側實時顯示當前鼠標位置
   - 可用于獲取點擊操作的精確坐標

4. 操作步驟:
   1) 選擇合適的模板或直接編輯JSON代碼
   2) 如需要坐標,移動鼠標到目標位置并記錄坐標
   3) 修改JSON中的參數(shù)
   4) 點擊"確認"保存設置

5. 注意事項:
   - JSON格式必須正確
   - 坐標值必須是整數(shù)
   - 文本內容需要用雙引號包圍
   - 組合鍵名稱必須是有效的鍵名
"""
        msg = QMessageBox()
        msg.setWindowTitle("鍵鼠操作編輯器使用說明")
        msg.setText(help_text)
        msg.setIcon(QMessageBox.Icon.Information)
        msg.exec()

class TaskManager(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("自動化任務管理器")
        self.setGeometry(100, 100, 1000, 800)
        
        # 初始化日志管理器和任務驗證器
        self.log_manager = LogManager()
        self.task_validator = TaskValidator()
        
        # 初始化任務列表和觀察者
        self.tasks = []
        self.file_observers = {}
        self.load_tasks()
        
        self.init_ui()
        
    def init_ui(self):
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        # 添加任務區(qū)域
        task_group = QWidget()
        task_layout = QVBoxLayout(task_group)
        
        # 第一行:基本信息
        basic_info = QHBoxLayout()
        
        # 任務類型選擇
        self.task_type = QComboBox()
        self.task_type.addItems([
            "打開程序", "關閉程序", "讀取文件", "寫入文件", 
            "系統(tǒng)操作", "鍵鼠操作", "網絡操作", "監(jiān)控文件"
        ])
        self.task_type.currentTextChanged.connect(self.on_task_type_changed)
        basic_info.addWidget(QLabel("任務類型:"))
        basic_info.addWidget(self.task_type)
        
        # 目標路徑
        self.target_path = QLineEdit()
        self.browse_btn = QPushButton("瀏覽...")
        self.browse_btn.clicked.connect(self.browse_path)
        basic_info.addWidget(QLabel("目標路徑:"))
        basic_info.addWidget(self.target_path)
        basic_info.addWidget(self.browse_btn)
        
        task_layout.addLayout(basic_info)
        
        # 第二行:時間設置
        time_layout = QHBoxLayout()
        
        # 時間類型
        self.time_type = QComboBox()
        self.time_type.addItems(["一次性", "每天", "每周", "每月", "每年", "文件觸發(fā)", "自定義間隔"])
        self.time_type.currentTextChanged.connect(self.on_time_type_changed)
        time_layout.addWidget(QLabel("執(zhí)行方式:"))
        time_layout.addWidget(self.time_type)
        
        # 時間輸入
        self.time_input = QLineEdit()
        time_layout.addWidget(QLabel("執(zhí)行時間:"))
        time_layout.addWidget(self.time_input)
        
        # 快速時間選擇按鈕
        quick_time_btn = QPushButton("快速選擇")
        quick_time_btn.clicked.connect(self.show_quick_time_menu)
        time_layout.addWidget(quick_time_btn)
        
        # 添加幫助按鈕
        help_btn = QPushButton("時間格式幫助")
        help_btn.clicked.connect(self.show_time_help)
        time_layout.addWidget(help_btn)
        
        # 間隔設置(默認隱藏)
        self.interval_spin = QSpinBox()
        self.interval_spin.setRange(1, 1000)
        self.interval_unit = QComboBox()
        self.interval_unit.addItems(["秒", "分鐘", "小時", "天"])
        self.interval_spin.hide()
        self.interval_unit.hide()
        time_layout.addWidget(self.interval_spin)
        time_layout.addWidget(self.interval_unit)
        
        task_layout.addLayout(time_layout)
        
        # 第三行:附加選項
        options_layout = QHBoxLayout()
        
        # 優(yōu)先級
        self.priority = QComboBox()
        self.priority.addItems(["低", "中", "高"])
        options_layout.addWidget(QLabel("優(yōu)先級:"))
        options_layout.addWidget(self.priority)
        
        # 是否啟用日志
        self.enable_log = QCheckBox("啟用日志")
        options_layout.addWidget(self.enable_log)
        
        # 任務描述
        self.description = QLineEdit()
        options_layout.addWidget(QLabel("描述:"))
        options_layout.addWidget(self.description)
        
        task_layout.addLayout(options_layout)
        
        # 添加任務按鈕
        buttons_layout = QHBoxLayout()
        add_button = QPushButton("添加任務")
        add_button.clicked.connect(self.add_task)
        buttons_layout.addWidget(add_button)
        
        # 導入導出按鈕
        import_button = QPushButton("導入任務")
        export_button = QPushButton("導出任務")
        import_button.clicked.connect(self.import_tasks)
        export_button.clicked.connect(self.export_tasks)
        buttons_layout.addWidget(import_button)
        buttons_layout.addWidget(export_button)
        
        task_layout.addLayout(buttons_layout)
        
        layout.addWidget(task_group)
        
        # 任務列表
        self.task_table = QTableWidget()
        self.task_table.setColumnCount(7)
        self.task_table.setHorizontalHeaderLabels([
            "任務類型", "目標路徑", "執(zhí)行時間", "優(yōu)先級", 
            "狀態(tài)", "描述", "操作"
        ])
        self.task_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.task_table.customContextMenuRequested.connect(self.show_context_menu)
        layout.addWidget(self.task_table)
        
        # 日志區(qū)域
        log_group = QWidget()
        log_layout = QVBoxLayout(log_group)
        log_layout.addWidget(QLabel("執(zhí)行日志:"))
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        log_layout.addWidget(self.log_text)
        layout.addWidget(log_group)
        
        # 設置日志控件
        self.log_manager.set_log_widget(self.log_text)
        
        # 啟動定時器
        self.timer = QTimer()
        self.timer.timeout.connect(self.check_tasks)
        self.timer.start(1000)
        
    def on_task_type_changed(self, task_type):
        if task_type == "系統(tǒng)操作":
            self.target_path.clear()
            self.target_path.setReadOnly(True)
            self.target_path.setPlaceholderText("系統(tǒng)操作無需設置路徑")
            self.browse_btn.setEnabled(False)
        elif task_type == "鍵鼠操作":
            self.target_path.clear()
            self.target_path.setReadOnly(True)
            self.target_path.setPlaceholderText("點擊編輯按鈕設置鍵鼠操作")
            self.browse_btn.setText("編輯")
            self.browse_btn.setEnabled(True)
            self.browse_btn.clicked.disconnect()
            self.browse_btn.clicked.connect(self.edit_mouse_keyboard)
        else:
            self.target_path.setReadOnly(False)
            self.target_path.setPlaceholderText("")
            self.browse_btn.setText("瀏覽...")
            self.browse_btn.setEnabled(True)
            self.browse_btn.clicked.disconnect()
            self.browse_btn.clicked.connect(self.browse_path)
            
    def on_time_type_changed(self, time_type):
        if time_type == "自定義間隔":
            self.time_input.hide()
            self.interval_spin.show()
            self.interval_unit.show()
        elif time_type == "文件觸發(fā)":
            self.time_input.hide()
            self.interval_spin.hide()
            self.interval_unit.hide()
        else:
            self.time_input.show()
            self.interval_spin.hide()
            self.interval_unit.hide()
            
            # 根據時間類型設置提示文本
            if time_type == "一次性":
                self.time_input.setPlaceholderText("示例:2024-03-20 15:30 或 15分鐘后")
            elif time_type == "每天":
                self.time_input.setPlaceholderText("示例:09:30(每天9點30分執(zhí)行)")
            elif time_type == "每周":
                self.time_input.setPlaceholderText("示例:星期一 09:30 或 1 09:30")
            elif time_type == "每月":
                self.time_input.setPlaceholderText("示例:1 09:30(每月1號9點30分)")
            elif time_type == "每年":
                self.time_input.setPlaceholderText("示例:03-01 09:30(每年3月1日9點30分)")
            
    def browse_path(self):
        task_type = self.task_type.currentText()
        if task_type in ["打開程序", "關閉程序"]:
            file_path, _ = QFileDialog.getOpenFileName(
                self, "選擇程序", "", 
                "可執(zhí)行文件 (*.exe *.bat *.cmd *.ps1);;所有文件 (*.*)"
            )
        else:
            file_path, _ = QFileDialog.getOpenFileName(self, "選擇文件")
        if file_path:
            self.target_path.setText(file_path)
            
    def add_task(self):
        try:
            task_type = self.task_type.currentText()
            target = self.target_path.text()
            time_type = self.time_type.currentText()
            
            # 驗證輸入
            if not target and task_type != "系統(tǒng)操作":
                QMessageBox.warning(self, "錯誤", "請輸入目標路徑", QMessageBox.StandardButton.Ok)
                return
                
            # 設置執(zhí)行時間
            if time_type == "自定義間隔":
                interval = self.interval_spin.value()
                unit = self.interval_unit.currentText()
                if unit == "秒":
                    delta = timedelta(seconds=interval)
                elif unit == "分鐘":
                    delta = timedelta(minutes=interval)
                elif unit == "小時":
                    delta = timedelta(hours=interval)
                else:
                    delta = timedelta(days=interval)
                # 使用精確時間計算
                current_time = datetime.now()
                execute_time = current_time.replace(microsecond=0) + delta
            elif time_type == "文件觸發(fā)":
                execute_time = "文件觸發(fā)"
            elif time_type == "每年":
                # 處理每年的時間格式
                time_str = self.time_input.text().strip()
                if not time_str:
                    QMessageBox.warning(self, "錯誤", "請輸入執(zhí)行時間", QMessageBox.StandardButton.Ok)
                    return
                    
                try:
                    parts = time_str.split()
                    if len(parts) != 2:
                        raise ValueError("每年任務的時間格式應為 'MM-DD HH:MM'")
                    
                    date_part, time_part = parts
                    month, day = map(int, date_part.split('-'))
                    hour, minute = map(int, time_part.split(':'))
                    
                    now = datetime.now()
                    try:
                        execute_time = now.replace(month=month, day=day, hour=hour, minute=minute, second=0, microsecond=0)
                        # 如果時間已過,設置為明年
                        if execute_time <= now:
                            execute_time = execute_time.replace(year=now.year + 1)
                    except ValueError as e:
                        if "day is out of range for month" in str(e):
                            raise ValueError("指定的日期超出了月份的有效范圍")
                        raise e
                except Exception as e:
                    raise ValueError(f"時間格式錯誤: {str(e)}")
            else:
                time_str = self.time_input.text().strip()
                if not time_str:
                    QMessageBox.warning(self, "錯誤", "請輸入執(zhí)行時間", QMessageBox.StandardButton.Ok)
                    return
                    
                try:
                    if "秒后" in time_str:
                        seconds = int(time_str.replace("秒后", "").strip())
                        current_time = datetime.now()
                        execute_time = current_time.replace(microsecond=0) + timedelta(seconds=seconds)
                    elif "分鐘后" in time_str:
                        minutes = int(time_str.replace("分鐘后", "").strip())
                        current_time = datetime.now()
                        execute_time = current_time.replace(microsecond=0) + timedelta(minutes=minutes)
                    elif time_type == "每天":
                        # 處理每天的時間格式 HH:MM
                        try:
                            hour, minute = map(int, time_str.split(':'))
                            now = datetime.now()
                            execute_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0)
                            # 如果時間已過,設置為明天
                            if execute_time <= now:
                                execute_time += timedelta(days=1)
                        except ValueError:
                            raise ValueError("每天任務的時間格式應為 HH:MM")
                    elif time_type == "每周":
                        # 處理每周的時間格式
                        parts = time_str.split()
                        if len(parts) != 2:
                            raise ValueError("每周任務的時間格式應為 '星期X HH:MM' 或 'X HH:MM'")
                        
                        weekday_str, time_part = parts
                        # 轉換星期為數(shù)字(0-6)
                        weekday_map = {
                            "星期一": 0, "星期二": 1, "星期三": 2, "星期四": 3,
                            "星期五": 4, "星期六": 5, "星期日": 6,
                            "周一": 0, "周二": 1, "周三": 2, "周四": 3,
                            "周五": 4, "周六": 5, "周日": 6,
                            "1": 0, "2": 1, "3": 2, "4": 3, "5": 4, "6": 5, "7": 6
                        }
                        if weekday_str not in weekday_map:
                            raise ValueError("無效的星期格式")
                        
                        target_weekday = weekday_map[weekday_str]
                        hour, minute = map(int, time_part.split(':'))
                        
                        # 計算下一個目標星期的日期
                        now = datetime.now()
                        days_ahead = target_weekday - now.weekday()
                        if days_ahead <= 0:  # 如果目標星期已過,設置為下周
                            days_ahead += 7
                        
                        execute_time = now.replace(hour=hour, minute=minute, second=0, microsecond=0) + timedelta(days=days_ahead)
                        
                    elif time_type == "每月":
                        # 處理每月的時間格式
                        parts = time_str.replace('日', '').split()
                        if len(parts) != 2:
                            raise ValueError("每月任務的時間格式應為 'DD HH:MM' 或 'DD日 HH:MM'")
                        
                        day = int(parts[0])
                        hour, minute = map(int, parts[1].split(':'))
                        
                        now = datetime.now()
                        try:
                            execute_time = now.replace(day=day, hour=hour, minute=minute, second=0, microsecond=0)
                            # 如果時間已過,設置為下個月
                            if execute_time <= now:
                                if now.month == 12:
                                    execute_time = execute_time.replace(year=now.year + 1, month=1)
                                else:
                                    execute_time = execute_time.replace(month=now.month + 1)
                        except ValueError as e:
                            if "day is out of range for month" in str(e):
                                raise ValueError("指定的日期超出了月份的有效范圍")
                            raise e
                    else:
                        # 嘗試解析完整的日期時間格式
                        try:
                            execute_time = parser.parse(time_str)
                        except:
                            raise ValueError("無效的時間格式")
                except Exception as e:
                    raise ValueError(f"時間格式錯誤: {str(e)}")
            
            task = {
                "type": task_type,
                "target": target,
                "time_type": time_type,
                "time": str(execute_time),
                "priority": self.priority.currentText(),
                "description": self.description.text(),
                "status": "等待中",
                "enable_log": self.enable_log.isChecked()
            }
            
            # 驗證任務數(shù)據
            self.task_validator.validate_task_data(task)
            
            # 如果是文件觸發(fā)類型,設置文件監(jiān)控
            if time_type == "文件觸發(fā)":
                self.setup_file_observer(task)
            
            self.tasks.append(task)
            self.save_tasks()
            self.update_task_table()
            
            # 記錄日志
            self.log_manager.write_log(f"添加新任務: {task['type']} - {task['description']}")
            
            # 清空輸入框
            self.time_input.clear()
            self.target_path.clear()
            self.description.clear()
            
        except Exception as e:
            QMessageBox.warning(self, "錯誤", f"添加任務失敗: {str(e)}", QMessageBox.StandardButton.Ok)
            
    def setup_file_observer(self, task):
        try:
            if task["target"] not in self.file_observers:
                event_handler = FileChangeHandler(lambda path: self.on_file_changed(task))
                observer = Observer()
                observer.schedule(event_handler, os.path.dirname(task["target"]), recursive=False)
                observer.start()
                self.file_observers[task["target"]] = observer
        except Exception as e:
            raise Exception(f"設置文件監(jiān)控失敗: {str(e)}")
            
    def cleanup_file_observer(self, task):
        if task["target"] in self.file_observers:
            try:
                self.file_observers[task["target"]].stop()
                self.file_observers[task["target"]].join()
                del self.file_observers[task["target"]]
            except Exception as e:
                print(f"清理文件監(jiān)控失敗: {str(e)}")
                
    def on_file_changed(self, task):
        self.execute_task(task)
        
    def show_context_menu(self, position):
        menu = QMenu()
        delete_action = menu.addAction("刪除任務")
        pause_action = menu.addAction("暫停任務")
        resume_action = menu.addAction("恢復任務")
        
        action = menu.exec(self.task_table.mapToGlobal(position))
        if action == delete_action:
            self.delete_selected_task()
        elif action == pause_action:
            self.pause_selected_task()
        elif action == resume_action:
            self.resume_selected_task()
            
    def delete_selected_task(self):
        current_row = self.task_table.currentRow()
        if current_row >= 0:
            task = self.tasks[current_row]
            # 清理文件監(jiān)控
            self.cleanup_file_observer(task)
            # 刪除任務
            del self.tasks[current_row]
            self.save_tasks()
            self.update_task_table()
            # 記錄日志
            self.log_manager.write_log(f"刪除任務: {task['type']} - {task['description']}")
            
    def pause_selected_task(self):
        current_row = self.task_table.currentRow()
        if current_row >= 0:
            task = self.tasks[current_row]
            task["status"] = "已暫停"
            # 如果是文件觸發(fā)類型,暫停文件監(jiān)控
            if task["time_type"] == "文件觸發(fā)":
                self.cleanup_file_observer(task)
            self.save_tasks()
            self.update_task_table()
            # 記錄日志
            self.log_manager.write_log(f"暫停任務: {task['type']} - {task['description']}")
            
    def resume_selected_task(self):
        current_row = self.task_table.currentRow()
        if current_row >= 0:
            task = self.tasks[current_row]
            task["status"] = "等待中"
            # 如果是文件觸發(fā)類型,重新啟動文件監(jiān)控
            if task["time_type"] == "文件觸發(fā)":
                self.setup_file_observer(task)
            self.save_tasks()
            self.update_task_table()
            # 記錄日志
            self.log_manager.write_log(f"恢復任務: {task['type']} - {task['description']}")
            
    def save_tasks(self):
        with open("tasks.json", "w", encoding="utf-8") as f:
            json.dump(self.tasks, f, ensure_ascii=False, indent=2)
            
    def load_tasks(self):
        try:
            if os.path.exists("tasks.json"):
                with open("tasks.json", "r", encoding="utf-8") as f:
                    self.tasks = json.load(f)
                    
                # 重新設置文件監(jiān)控
                for task in self.tasks:
                    if task["time_type"] == "文件觸發(fā)":
                        self.setup_file_observer(task)
        except Exception as e:
            print(f"加載任務失敗: {str(e)}")
            
    def import_tasks(self):
        file_path, _ = QFileDialog.getOpenFileName(self, "導入任務", "", "JSON文件 (*.json)")
        if file_path:
            try:
                with open(file_path, "r", encoding="utf-8") as f:
                    imported_tasks = json.load(f)
                    
                # 驗證所有導入的任務
                for task in imported_tasks:
                    self.task_validator.validate_task_data(task)
                    
                # 導入任務
                self.tasks.extend(imported_tasks)
                
                # 設置文件監(jiān)控
                for task in imported_tasks:
                    if task["time_type"] == "文件觸發(fā)" and task["status"] == "等待中":
                        self.setup_file_observer(task)
                        
                self.save_tasks()
                self.update_task_table()
                
                # 記錄日志
                self.log_manager.write_log(f"導入{len(imported_tasks)}個任務")
                QMessageBox.information(self, "成功", "任務導入成功", QMessageBox.StandardButton.Ok)
                
            except Exception as e:
                QMessageBox.warning(self, "錯誤", f"導入任務失敗: {str(e)}", QMessageBox.StandardButton.Ok)
                
    def export_tasks(self):
        file_path, _ = QFileDialog.getSaveFileName(self, "導出任務", "", "JSON文件 (*.json)")
        if file_path:
            try:
                with open(file_path, "w", encoding="utf-8") as f:
                    json.dump(self.tasks, f, ensure_ascii=False, indent=2)
                QMessageBox.information(self, "成功", "任務導出成功", QMessageBox.StandardButton.Ok)
            except Exception as e:
                QMessageBox.warning(self, "錯誤", f"導出任務失敗: {str(e)}", QMessageBox.StandardButton.Ok)
                
    def update_task_table(self):
        self.task_table.setRowCount(len(self.tasks))
        for i, task in enumerate(self.tasks):
            self.task_table.setItem(i, 0, QTableWidgetItem(task["type"]))
            self.task_table.setItem(i, 1, QTableWidgetItem(task["target"]))
            self.task_table.setItem(i, 2, QTableWidgetItem(str(task["time"])))
            self.task_table.setItem(i, 3, QTableWidgetItem(task["priority"]))
            self.task_table.setItem(i, 4, QTableWidgetItem(task["status"]))
            self.task_table.setItem(i, 5, QTableWidgetItem(task["description"]))
            
            # 添加操作按鈕
            btn_widget = QWidget()
            btn_layout = QHBoxLayout(btn_widget)
            delete_btn = QPushButton("刪除")
            delete_btn.clicked.connect(lambda checked, row=i: self.delete_task(row))
            btn_layout.addWidget(delete_btn)
            self.task_table.setCellWidget(i, 6, btn_widget)
            
    def check_tasks(self):
        current_time = datetime.now()
        for task in self.tasks:
            if task["status"] == "等待中":
                if task["time_type"] == "文件觸發(fā)":
                    continue  # 文件觸發(fā)類型由文件監(jiān)控處理
                    
                execute_time = parser.parse(task["time"])
                if current_time >= execute_time:
                    self.execute_task(task)
                    
                    # 根據時間類型更新下次執(zhí)行時間
                    if task["time_type"] == "每天":
                        next_time = execute_time + timedelta(days=1)
                    elif task["time_type"] == "每周":
                        next_time = execute_time + timedelta(weeks=1)
                    elif task["time_type"] == "每月":
                        if execute_time.month == 12:
                            next_time = execute_time.replace(year=execute_time.year + 1, month=1)
                        else:
                            next_time = execute_time.replace(month=execute_time.month + 1)
                    elif task["time_type"] == "每年":
                        next_time = execute_time.replace(year=execute_time.year + 1)
                    else:
                        task["status"] = "已完成"
                        continue
                        
                    task["time"] = str(next_time)
                    
        self.update_task_table()
        self.save_tasks()

    def execute_task(self, task):
        try:
            result = "執(zhí)行成功"
            
            # 驗證目標路徑(鍵鼠操作除外)
            if task["type"] not in ["系統(tǒng)操作", "鍵鼠操作"]:
                if not os.path.exists(task["target"]):
                    raise FileNotFoundError(f"目標路徑不存在: {task['target']}")
            
            if task["type"] == "打開程序":
                subprocess.Popen(task["target"])
            elif task["type"] == "關閉程序":
                process_name = os.path.basename(task["target"])
                for proc in psutil.process_iter(['name']):
                    if proc.info['name'] == process_name:
                        proc.kill()
            elif task["type"] == "讀取文件":
                with open(task["target"], 'r', encoding='utf-8') as f:
                    content = f.read()
                    print(content)
                    result = f"讀取內容: {content[:100]}..."
            elif task["type"] == "寫入文件":
                with open(task["target"], 'w', encoding='utf-8') as f:
                    f.write("寫入測試內容")
            elif task["type"] == "系統(tǒng)操作":
                if task["target"] == "關機":
                    os.system("shutdown /s /t 60")
                elif task["target"] == "重啟":
                    os.system("shutdown /r /t 60")
                elif task["target"] == "休眠":
                    os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
            elif task["type"] == "鍵鼠操作":
                try:
                    action_data = json.loads(task["target"])
                    if action_data.get("type") == "wechat_login":
                        # 使用 wxauto 實現(xiàn)微信登錄
                        try:
                            # 檢查微信進程是否存在
                            wechat_running = False
                            wechat_pid = None
                            for proc in psutil.process_iter(['name', 'pid']):
                                if proc.info['name'].lower() in ['wechat.exe', 'weixin.exe']:
                                    wechat_running = True
                                    wechat_pid = proc.info['pid']
                                    break

                            if wechat_running and wechat_pid:
                                # 如果微信已在運行,先關閉它
                                psutil.Process(wechat_pid).terminate()
                                time.sleep(2)  # 等待進程完全關閉

                            # 啟動新的微信實例
                            wechat_path = None
                            possible_paths = [
                                os.path.expandvars(r"%ProgramFiles%\Tencent\WeChat\WeChat.exe"),
                                os.path.expandvars(r"%ProgramFiles(x86)%\Tencent\WeChat\WeChat.exe"),
                                r"C:\Program Files\Tencent\WeChat\WeChat.exe",
                                r"C:\Program Files (x86)\Tencent\WeChat\WeChat.exe"
                            ]
                            
                            for path in possible_paths:
                                if os.path.exists(path):
                                    wechat_path = path
                                    break
                            
                            if not wechat_path:
                                raise Exception("找不到微信安裝路徑")

                            # 啟動微信
                            subprocess.Popen(wechat_path)
                            time.sleep(8)  # 等待微信完全啟動
                            
                            # 使用wxauto處理登錄
                            retry_count = 0
                            success = False
                            while retry_count < 5:  # 最多嘗試5次
                                try:
                                    wx = WeChat()
                                    if wx.WindowStatus == 1:  # 窗口正常
                                        if wx.LoginStatus == 0:  # 未登錄
                                            wx.ClickLogin()  # 使用wxauto的方法點擊登錄
                                            success = True
                                            result = "微信登錄操作執(zhí)行完成"
                                            break
                                        else:
                                            success = True
                                            result = "微信已經處于登錄狀態(tài)"
                                            break
                                except Exception as e:
                                    print(f"第{retry_count + 1}次嘗試失?。簕str(e)}")
                                    retry_count += 1
                                    time.sleep(2)
                            
                            if not success:
                                raise Exception("無法完成登錄操作,請手動檢查微信窗口狀態(tài)")
                                
                        except Exception as e:
                            raise Exception(f"微信登錄操作失敗: {str(e)}")
                    elif action_data.get("type") == "click":
                        # 添加短暫延時確保鼠標移動到位
                        time.sleep(0.5)
                        # 先移動到目標位置
                        pyautogui.moveTo(action_data["x"], action_data["y"], duration=0.2)
                        # 再執(zhí)行點擊
                        time.sleep(0.2)
                        pyautogui.click()
                        result = f"點擊坐標 ({action_data['x']}, {action_data['y']}) 完成"
                    elif action_data.get("type") == "type":
                        time.sleep(0.5)  # 等待輸入框準備就緒
                        pyautogui.typewrite(action_data["text"], interval=0.1)  # 添加輸入間隔
                        result = f"輸入文本 '{action_data['text']}' 完成"
                    elif action_data.get("type") == "hotkey":
                        time.sleep(0.5)  # 等待系統(tǒng)準備就緒
                        pyautogui.hotkey(*action_data["keys"])
                        result = f"執(zhí)行快捷鍵 {'+'.join(action_data['keys'])} 完成"
                    else:
                        raise ValueError(f"未知的鍵鼠操作類型: {action_data.get('type')}")
                except json.JSONDecodeError:
                    raise ValueError("無效的鍵鼠操作JSON格式")
                except pyautogui.FailSafeException:
                    raise Exception("操作被用戶中斷(鼠標移動到屏幕角落觸發(fā)安全機制)")
                except Exception as e:
                    raise Exception(f"鍵鼠操作執(zhí)行失敗: {str(e)}")
            elif task["type"] == "網絡操作":
                # 這里可以添加網絡相關操作的實現(xiàn)
                pass
                
            # 記錄日志
            if task["enable_log"]:
                self.log_manager.write_log(f"執(zhí)行任務: {task['type']} - {task['description']}: {result}")
                
        except Exception as e:
            error_msg = f"執(zhí)行任務失敗: {str(e)}"
            print(error_msg)
            if task["enable_log"]:
                self.log_manager.write_log(f"執(zhí)行任務失敗: {task['type']} - {task['description']}: {error_msg}")

    def show_quick_time_menu(self):
        menu = QMenu(self)
        time_type = self.time_type.currentText()
        
        if time_type == "一次性":
            # 添加秒選項
            for seconds in [5, 10, 30]:
                action = menu.addAction(f"{seconds}秒后")
                action.triggered.connect(lambda checked, s=seconds: self.time_input.setText(f"{s}秒后"))
            
            menu.addSeparator()
            
            # 添加相對時間選項
            for minutes in [1, 5, 10, 15, 30, 60]:
                action = menu.addAction(f"{minutes}分鐘后")
                action.triggered.connect(lambda checked, m=minutes: self.time_input.setText(f"{m}分鐘后"))
            
            menu.addSeparator()
            
            # 添加今明兩天的常用時間點
            now = datetime.now()
            today = now.date()
            tomorrow = today + timedelta(days=1)
            
            for hour in [9, 12, 15, 18, 21]:
                # 今天的時間點(只添加未來的時間點)
                time_point = now.replace(hour=hour, minute=0, second=0, microsecond=0)
                if time_point > now:
                    action = menu.addAction(f"今天 {hour:02d}:00")
                    action.triggered.connect(
                        lambda checked, t=time_point: self.time_input.setText(t.strftime("%Y-%m-%d %H:%M"))
                    )
                
                # 明天的時間點
                time_point = datetime.combine(tomorrow, datetime.min.time().replace(hour=hour))
                action = menu.addAction(f"明天 {hour:02d}:00")
                action.triggered.connect(
                    lambda checked, t=time_point: self.time_input.setText(t.strftime("%Y-%m-%d %H:%M"))
                )
                
        elif time_type == "每天":
            for hour in [9, 12, 15, 18, 21]:
                for minute in [0, 30]:
                    time_str = f"{hour:02d}:{minute:02d}"
                    action = menu.addAction(time_str)
                    action.triggered.connect(lambda checked, t=time_str: self.time_input.setText(t))
                    
        elif time_type == "每周":
            weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
            for weekday in weekdays:
                submenu = menu.addMenu(weekday)
                for hour in [9, 12, 15, 18, 21]:
                    action = submenu.addAction(f"{hour:02d}:00")
                    action.triggered.connect(
                        lambda checked, w=weekday, h=hour: self.time_input.setText(f"{w} {h:02d}:00")
                    )
                    
        elif time_type == "每月":
            for day in [1, 5, 10, 15, 20, 25, 30]:
                submenu = menu.addMenu(f"{day}日")
                for hour in [9, 12, 15, 18, 21]:
                    action = submenu.addAction(f"{hour:02d}:00")
                    action.triggered.connect(
                        lambda checked, d=day, h=hour: self.time_input.setText(f"wppm3vysvbp {h:02d}:00")
                    )
        
        elif time_type == "每年":
            # 添加一些重要的年度日期
            special_dates = [
                ("元旦", "01-01"),
                ("春節(jié)", "02-01"),  # 這里使用陽歷示例
                ("勞動節(jié)", "05-01"),
                ("國慶節(jié)", "10-01"),
                ("元旦前夕", "12-31")
            ]
            
            for name, date in special_dates:
                submenu = menu.addMenu(name)
                for hour in [0, 8, 9, 12, 15, 18, 21]:
                    time_str = f"{date} {hour:02d}:00"
                    action = submenu.addAction(f"{hour:02d}:00")
                    action.triggered.connect(
                        lambda checked, t=time_str: self.time_input.setText(t)
                    )
            
            menu.addSeparator()
            
            # 添加每月第一天
            for month in range(1, 13):
                time_str = f"{month:02d}-01 09:00"
                action = menu.addAction(f"{month}月1日 09:00")
                action.triggered.connect(
                    lambda checked, t=time_str: self.time_input.setText(t)
                )
        
        menu.exec(QCursor.pos())

    def show_time_help(self):
        help_text = """
時間格式說明:

1. 一次性任務:
   - 絕對時間:2024-03-20 15:30
   - 相對時間:
     * X秒后(如:30秒后)
     * X分鐘后(如:15分鐘后)
   - 支持格式:
     * YYYY-MM-DD HH:MM
     * YYYY/MM/DD HH:MM
     * X秒后(X為數(shù)字)
     * X分鐘后(X為數(shù)字)

2. 每天任務:
   - 格式:HH:MM
   - 示例:09:30、15:00
   - 說明:每天在指定時間執(zhí)行

3. 每周任務:
   - 格式一:星期X HH:MM
   - 格式二:周X HH:MM
   - 格式三:X HH:MM(X為1-7,表示周一到周日)
   - 示例:
     * 星期一 09:30
     * 周五 15:00
     * 1 09:30(周一 9:30)

4. 每月任務:
   - 格式一:DD HH:MM
   - 格式二:DD日 HH:MM
   - 示例:
     * 1 09:30(每月1號9:30)
     * 15日 15:00(每月15號15:00)

5. 每年任務:
   - 格式:MM-DD HH:MM
   - 示例:
     * 03-01 09:30(每年3月1日9:30)
     * 12-25 00:00(每年圣誕節(jié)零點)
   - 說明:月份和日期使用數(shù)字,用連字符分隔

6. 文件觸發(fā):
   - 無需填寫時間
   - 當文件發(fā)生變化時自動觸發(fā)

7. 自定義間隔:
   - 使用下拉框選擇間隔時間和單位(秒/分鐘/小時/天)
   - 從當前時間開始計算

提示:
- 使用24小時制
- 分鐘必須是兩位數(shù)(如:09:05,而不是9:5)
- 可以使用"快速選擇"按鈕選擇常用時間
"""
        msg = QMessageBox()
        msg.setWindowTitle("時間格式說明")
        msg.setText(help_text)
        msg.setIcon(QMessageBox.Icon.Information)
        msg.exec()

    def delete_task(self, row):
        """刪除指定行的任務"""
        if 0 <= row < len(self.tasks):
            task = self.tasks[row]
            # 清理文件監(jiān)控
            self.cleanup_file_observer(task)
            # 刪除任務
            del self.tasks[row]
            self.save_tasks()
            self.update_task_table()
            # 記錄日志
            self.log_manager.write_log(f"刪除任務: {task['type']} - {task['description']}")

    def edit_mouse_keyboard(self):
        editor = MouseKeyboardEditor(self)
        if self.target_path.text():
            try:
                # 如果已有內容,加載到編輯器中
                editor.code_editor.setPlainText(self.target_path.text())
            except:
                pass
                
        if editor.exec() == QDialog.DialogCode.Accepted:
            try:
                # 驗證JSON格式
                json_str = editor.get_code()
                json.loads(json_str)  # 驗證JSON是否有效
                self.target_path.setText(json_str)
            except json.JSONDecodeError:
                QMessageBox.warning(self, "錯誤", "無效的JSON格式", QMessageBox.StandardButton.Ok)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = TaskManager()
    window.show()
    sys.exit(app.exec()) 

到此這篇關于Python利用PyQt6開發(fā)一個全能的任務管理器的文章就介紹到這了,更多相關Python任務管理器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • pygame實現(xiàn)雷電游戲雛形開發(fā)

    pygame實現(xiàn)雷電游戲雛形開發(fā)

    這篇文章主要為大家詳細介紹了pygame實現(xiàn)雷電游戲開發(fā)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • python基于pygame實現(xiàn)飛機大作戰(zhàn)小游戲

    python基于pygame實現(xiàn)飛機大作戰(zhàn)小游戲

    這篇文章主要為大家詳細介紹了python基于pygame實現(xiàn)飛機大作戰(zhàn)小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • 總結Pyinstaller的坑及終極解決方法(小結)

    總結Pyinstaller的坑及終極解決方法(小結)

    這篇文章主要介紹了總結Pyinstaller的坑及終極解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Matlab之使用HeatMap實現(xiàn)畫熱圖

    Matlab之使用HeatMap實現(xiàn)畫熱圖

    這篇文章主要介紹了Matlab之使用HeatMap實現(xiàn)畫熱圖方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • python基礎之局部變量和全局變量

    python基礎之局部變量和全局變量

    這篇文章主要介紹了python局部變量和全局變量,實例分析了Python中返回一個返回值與多個返回值的方法,需要的朋友可以參考下
    2021-10-10
  • Python實現(xiàn)環(huán)形鏈表

    Python實現(xiàn)環(huán)形鏈表

    這篇文章主要為大家詳細介紹了Python實現(xiàn)環(huán)形鏈表,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 使用Python+Bright Data MCP實時抓取Google搜索結果完整教程

    使用Python+Bright Data MCP實時抓取Google搜索結果完整教程

    在 AI 應用和智能代理(Agent)的開發(fā)中,實時性數(shù)據往往是決定效果的關鍵,但傳統(tǒng)的網頁數(shù)據獲取方式存在明顯痛點,而 Bright Data 的 Web MCP Server正好可以解決這些問題,本文就給大家介紹了使用Python+Bright Data MCP實時抓取Google搜索結果完整教程
    2025-08-08
  • 使用Python求解最大公約數(shù)的實現(xiàn)方法

    使用Python求解最大公約數(shù)的實現(xiàn)方法

    這篇文章主要介紹了使用Python求解最大公約數(shù)的實現(xiàn)方法,包括用Python表示歐幾里得算法和Stein算法的求解原理,需要的朋友可以參考下
    2015-08-08
  • Python實現(xiàn)投影法分割圖像示例(一)

    Python實現(xiàn)投影法分割圖像示例(一)

    今天小編就為大家分享一篇Python實現(xiàn)投影法分割圖像示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-01-01
  • python 實現(xiàn)二維數(shù)組的索引、刪除、拼接操作

    python 實現(xiàn)二維數(shù)組的索引、刪除、拼接操作

    這篇文章主要介紹了python 實現(xiàn)二維數(shù)組的索引、刪除、拼接操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評論

恭城| 惠州市| 石楼县| 星座| 大化| 仙居县| 峡江县| 利津县| 东乡县| 科技| 松江区| 鞍山市| 丰宁| 牡丹江市| 兰考县| 宝兴县| 诸城市| 大余县| 图们市| 长兴县| 芷江| 五莲县| 于田县| 乃东县| 武强县| 宾阳县| 丹阳市| 丁青县| 井冈山市| 侯马市| 方正县| 孟津县| 长岭县| 敦化市| 岳阳市| 木兰县| 静海县| 东乡族自治县| 湄潭县| 灵璧县| 双城市|