程序功能
1.运行后可检测当前是否运行QQ,微信,企业微信等
2.可检测当前指定文件夹是否新增文件或文件夹
3.运行时带有进度条显示,提示内容正确错误等,带有配置文件
介绍完程序功能后,上代码:
下面 是主程序,该程序主要由 main.py 构成。
import sys
import os
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import psutil
import pygetwindow
import configparser
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
base_dir = os.path.dirname(__file__)
#pyrcc5 -o 目标文件名 源文件名
#https://blog.csdn.net/weixin_42296333/article/details/81178915
import resource
#该resource 就是pyrcc5生成的py文件
# 英文进程名称到中文名称的映射
PROCESS_MAPPING = {
'QQ.exe': 'QQ',
'WeChat.exe': '微信',
'WXWork.exe': '企业微信'
}
QQ_DEVICE_PROCESS_MAPPING = {
'IPhone': '我的IPhone手机',
'IPad': '我的IPad',
'Android': '我的Android手机'
}
def check_process(process_name):
for proc in psutil.process_iter(['name']):
if process_name.lower() in proc.info['name'].lower():
return True
return False
def show_message_icon_ok(messagebox,dir=":",icon_ok_path= 'icons8-ok-64.ico'):
#if os.path.exists(os.path.join(base_dir, dir, icon_ok_path)):
messagebox.setWindowIcon(QIcon(os.path.join(dir, icon_ok_path)))#
class Config:
config_file = 'settings.ini'
@staticmethod
def save_config(option):
config = configparser.ConfigParser()
config.read(Config.config_file)
if not config.has_section('Options'):
config.add_section('Options')
config.set('Options', 'selected_option', option)
with open(Config.config_file, 'w') as f:
config.write(f)
@staticmethod
def load_config():
config = configparser.ConfigParser()
config.read(Config.config_file)
if config.has_section('Options') and config.has_option('Options', 'selected_option'):
return config.get('Options', 'selected_option')
return ''
class FileChangeHandler(FileSystemEventHandler):
def __init__(self, window, selected_extension, desktop_path,src_file_path, check_file_change):
super().__init__()
self.window = window
self.selected_extension = selected_extension
self.desktop_path = desktop_path
self.check_file_change = check_file_change
self.src_file_path = src_file_path
self.on_modified_status = False
def clear_on_modified_status(self):
self.on_modified_status = False
pass
def Get_on_modified_status(self):
return self.on_modified_status
def on_created(self, event):
if self.check_file_change:
if os.path.isdir(event.src_path):
self.on_modified_status = True
self.src_file_path = event.src_path
self.window.save_folder_path(event.src_path)
else:
_, ext = os.path.splitext(event.src_path)
if ext.lower() == self.selected_extension.lower():
self.window.save_file_path(event.src_path)
pass
def on_modified(self, event):
if event.src_path.endswith(self.selected_extension):
self.on_modified_status = True
self.src_file_path = event.src_path
pass
if self.check_file_change:
if os.path.isdir(event.src_path):
self.window.save_folder_path(event.src_path)
else:
_, ext = os.path.splitext(event.src_path)
if ext.lower() == self.selected_extension.lower():
self.window.save_file_path(event.src_path)
class CheckProcessesThread(QThread):
process_found = pyqtSignal(list)
def __init__(self, selected_processes):
super().__init__()
self.selected_processes = selected_processes
def run(self):
found_processes = []
QQ_str = "QQ"
for name in self.selected_processes:
if check_process(name) and name.find(QQ_str) == 0:
#print("QQ find")
#find QQ device by name
found_processes.append(QQ_DEVICE_PROCESS_MAPPING.get(Config.load_config(), name))
break
if check_process(name):
found_processes.append(PROCESS_MAPPING.get(name, name)) # 映射为中文名称
self.process_found.emit(found_processes)
#print(found_processes)
class FileWatcherThread(QThread):
file_modified = pyqtSignal(str)
def __init__(self, window, selected_extension, desktop_path):
super().__init__()
self.window = window
self.selected_extension = selected_extension
self.desktop_path = desktop_path
self.event_handler = None
self.src_file_path = None
def run(self):
self.event_handler = FileChangeHandler(self.window, self.selected_extension, self.desktop_path,self.src_file_path, True)
observer = Observer()
observer.schedule(self.event_handler, self.desktop_path, recursive=True)
observer.start()
# 使用定时器每隔1秒检查文件变化
while True:
# 每隔一段时间检查文件变化
if self.event_handler.Get_on_modified_status():
self.event_handler.clear_on_modified_status()
self.file_modified.emit(self.event_handler.src_file_path)
self.sleep(1) # 暂停1秒钟
pass
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("进程检查工具")
self.settings = QSettings("settings.ini", QSettings.IniFormat)
self.initUI()
def initUI(self):
layout = QVBoxLayout()#主布局
#水平布局1
file_type_layout=QHBoxLayout()
# 文件类型标签
self.file_type_label = QLabel("请选择你想检查的文件类型:")
#self.file_type_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
file_type_layout.addWidget(self.file_type_label)
# 设置窗口图标
icon_path = ':/icon8.ico'
#if os.path.exists(icon_path):
self.setWindowIcon(QIcon(icon_path))
self.extension_combobox = QComboBox()
extensions = ['.txt', '.png', '.jpg', '.jpeg']
self.extension_combobox.addItems(extensions) # 文件后缀选项
#self.extension_combobox.setContentsMargins(0,0,0,0)
file_type_layout.addWidget(self.extension_combobox)
#file_type_layout.setAlignment(Qt.AlignBottom)
# 设置水平布局中的间距为0
#file_type_layout.setSpacing(0)
layout.addLayout(file_type_layout)
#水平布局2
desktop_layout = QHBoxLayout()
desktop_layout.addWidget(QPushButton("选择桌面路径", clicked=self.select_desktop_path))
self.desktop_path_edit = QLineEdit()
desktop_layout.addWidget(self.desktop_path_edit)
layout.addLayout(desktop_layout)
self.load_settings()
self.process_list = QListWidget()
self.process_list.addItems(['QQ.exe', 'WeChat.exe', 'WXWork.exe'])
layout.addWidget(self.process_list)
#add QRadioButton选项按钮
self.radio_iphone = QRadioButton("IPhone")
self.radio_ipad = QRadioButton("IPad")
self.radio_android = QRadioButton("Android")
layout.addWidget(self.radio_iphone)
layout.addWidget(self.radio_ipad)
layout.addWidget(self.radio_android)
# 加载配置
selected_option = Config.load_config()
if selected_option == 'IPhone':
self.radio_iphone.setChecked(True)
elif selected_option == 'IPad':
self.radio_ipad.setChecked(True)
elif selected_option == 'Android':
self.radio_android.setChecked(True)
#end
self.start_button = QPushButton("开始检查进程")
self.start_button.clicked.connect(self.start_check_processes)
layout.addWidget(self.start_button)
self.file_change_button = QPushButton("检测文件变化")
self.file_change_button.clicked.connect(self.start_check_file_change)
layout.addWidget(self.file_change_button)
self.file_change_button.setEnabled(False) # 初始化时禁用检测文件变化按钮
self.progress_bar = QProgressBar()
layout.addWidget(self.progress_bar)
self.progress_bar.setValue(0)
self.setLayout(layout)
# 选项按钮点击事件
self.radio_iphone.clicked.connect(lambda: self.save_option('IPhone'))
self.radio_ipad.clicked.connect(lambda: self.save_option('IPad'))
self.radio_android.clicked.connect(lambda: self.save_option('Android'))
#end
def load_settings(self):
desktop_path = self.settings.value("desktop_path", defaultValue="")
self.desktop_path_edit.setText(desktop_path)
extension_index = self.settings.value("selected_extension_index", defaultValue=0)
self.extension_combobox.setCurrentIndex(int(extension_index))
def save_settings(self):
desktop_path = self.desktop_path_edit.text()
self.settings.setValue("desktop_path", desktop_path)
extension_index = self.extension_combobox.currentIndex()
self.settings.setValue("selected_extension_index", extension_index)
def select_desktop_path(self):
desktop_path = QFileDialog.getExistingDirectory(self, "选择桌面路径", os.path.expanduser('~'))
self.desktop_path_edit.setText(desktop_path)
def save_folder_path(self, folder_path):
self.settings.setValue("folder_path", folder_path)
def save_file_path(self, file_path):
self.settings.setValue("file_path", file_path)
def setup_file_watcher(self):
selected_extension = self.extension_combobox.currentText() # 获取用户选择的文件后缀
desktop_path = self.desktop_path_edit.text() # 获取用户输入的桌面路径
self.file_watcher_thread = FileWatcherThread(self, selected_extension, desktop_path)
self.file_watcher_thread.file_modified.connect(self.file_modified_handler)
self.file_watcher_thread.start()
#print("File watcher thread started")
def start_check_processes(self):
self.progress_bar.setValue(0)
selected_processes = [item.text() for item in self.process_list.selectedItems()]
self.check_processes_thread = CheckProcessesThread(selected_processes)
self.check_processes_thread.process_found.connect(self.show_process_result)
self.check_processes_thread.start()
def show_process_result(self, found_processes):
if found_processes:
self.progress_bar.setValue(50)
msg_box = QMessageBox()
msg_box.setWindowTitle("检测结果")
show_message_icon_ok(msg_box)
msg_box.setText(f"发现进程: {', '.join(found_processes)}")
QTimer.singleShot(3000, msg_box.close) # 3秒后关闭消息框
msg_box.exec_()
# 将进程调至前台并最大化
for process_name in found_processes:
window = pygetwindow.getWindowsWithTitle(process_name)
if len(window)== 0:
QMessageBox.information(self, "检测结果", "未发现目标实例化窗口")
break
window = window[0]
window.maximize()
self.file_change_button.setEnabled(True) # 检查到进程后启用检查文件变化按钮
else:
QMessageBox.information(self, "检测结果", "未发现任何目标进程")
def start_check_file_change(self):
self.progress_bar.setValue(60)
desktop_path = self.desktop_path_edit.text() # 获取用户输入的桌面路径
msg_box = QMessageBox()
msg_box.setWindowTitle("检测文件变化")
show_message_icon_ok(msg_box,icon_ok_path= 'icons8-threads-48.ico')
msg_box.setText(f"开启线程,检测路径为:{desktop_path}")
QTimer.singleShot(3000, msg_box.close)
msg_box.exec_()
self.setup_file_watcher()
def file_modified_handler(self,str_path):
self.progress_bar.setValue(100)
msg_box = QMessageBox()
msg_box.setWindowTitle("检测到文件变化")
show_message_icon_ok(msg_box,icon_ok_path= 'icons8-threads-48.ico')
msg_box.setText(f"文件路径为:{str_path}")
QTimer.singleShot(3000, msg_box.close)
msg_box.exec_()
pass
def save_option(self, option):
Config.save_config(option)
def closeEvent(self, event):
self.save_settings()
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setWindowIcon(QIcon(':/icon8.ico'))
window = MainWindow()
window.show()
sys.exit(app.exec_())
说明:
若 运行以上代码请注意安装python库,尤其是pyQt5
1. 加载ico 文件时 需注意,首先应该新建qrc文件,将ico 文件路径写入到该文件内,具体写法已在上方代码中 给出具体链接。文件路径指定后,然后敲入下面命名,生成一个py文件,供main.py调用。
pyrcc5 -o 目标文件名 源文件名 (安装pyQt5库 就有这个命令)
2. qrc 文件基本结构
<RCC>
<qresource prefix="/">
<file>icon8.ico</file>
<file>icons8-ok-64.ico</file>
<file>icons8-threads-48.ico</file>
</qresource>
</RCC>
上述代码中的ico 文件为自定义ico文件,可根据自己爱好,选择合适的就行。
文件名不同,需要在main.py文件里面同步更新。
3.输入pyinstaller -F -w main.py -i icon8.ico (确保你的python环境安装了pyinstall)
然后就生成了main.exe (不知道为啥,这个exe有点大)
谢谢观赏,觉得对你有用,点个赞吧