之前公司有个需求,有一个本地文件夹中会不定时产生一些生产日志文件,要求写一个exe程序定时将这个文件夹中的文件上传到公司服务器,并将已上传的文件移动到另一个文件夹作为备份。此处给出一个简化的版本,用Python和PyQt5实现定时删除文价夹中文件的功能。
最后再打包为exe文件运行,打包可以用pyinstaller、nuitka等完成,我最开始使用的是pyinstaller,但是好像需要关闭电脑防火墙,由于我是用的公司电脑,权限控制的比较严,我没有权限关闭防火墙,所以改用nuitka完美解决。
PyQt5绘制图形界面:
class Ui_MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 创建一个QTimer实例
self.timer = QTimer(self)
# 连接QTimer的timeout信号到另一个槽函数
self.timer.timeout.connect(self.check_and_delete_files)
# 布局设置
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(331, 231)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setGeometry(QtCore.QRect(50, 30, 241, 121))
self.textBrowser.setObjectName("textBrowser")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(10, 30, 72, 15))
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(50, 170, 93, 28))
self.pushButton.clicked.connect(self.on_pushButton_clicked) # 绑定点击事件
self.pushButton.setObjectName("pushButton")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(200, 170, 93, 28))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_3.clicked.connect(self.on_pushButton3_clicked) # 绑定点击事件
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 按钮标签
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "定时任务"))
self.label_2.setText(_translate("MainWindow", "记录:"))
self.pushButton.setText(_translate("MainWindow", "启动"))
self.pushButton_3.setText(_translate("MainWindow", "退出"))
删除文件代码:
def delete_files_in_directory(directory):
# 遍历目录中的所有文件和子目录
deleted_count = 0 # 初始化计数器(删除了几个文件)
for filename in os.listdir(directory):
file_path = os.path.join(directory, filename)
try:
# 如果是文件,则删除
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
deleted_count += 1
elif os.path.isdir(file_path):
# 这里我们不删除子目录,只删除文件
# 如果需要删除空目录,可以在此处添加逻辑
pass
except Exception as e:
print(f"Error while deleting {file_path}: {e}")
return deleted_count
定时任务不能中断主程序的运行,因此需要使用@pyqtSlot()插槽来实现,以下为定时任务逻辑部分代码:
# 点击启动按钮逻辑
def on_pushButton_clicked(self):
# 当pushButton被点击时执行的代码
if self.pushButton.text() == '启动':
self.textBrowser.append("定时任务已启动......")
self.pushButton.setText('暂停')
# 开始定时器,例如每3秒触发一次(interval为定时时间)
self.timer.start(interval)
else:
self.textBrowser.append("定时任务已暂停......")
self.pushButton.setText('启动')
self.timer.stop() # 停止定时器
# 点击退出按钮逻辑
def on_pushButton3_clicked(self):
# 当pushButton_3被点击时执行的代码
QtWidgets.QApplication.quit() # 退出应用程序
# 插槽,定时任务
@pyqtSlot()
def check_and_delete_files(self):
if not os.path.exists(directory_to_clean): # 没有该文件夹
self.textBrowser.append(f"<span style='color:red;'>文件夹:{directory_to_clean}不存在</span>") # 报错日志
self.pushButton.setText('启动')
self.timer.stop() # 停止定时器
else:
deleted_count = delete_files_in_directory(directory_to_clean) # 删除文件
now_time = QDateTime.currentDateTime().toString('yyyy-MM-dd HH:mm:ss')
log = f'{now_time}--已删除{deleted_count}个文件'
self.textBrowser.append(log) # 打印日志
没有目标文件夹则会报错,并停止运行:
以下附项目完整源码:
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QTimer, QDateTime, pyqtSlot
from PyQt5.QtWidgets import *
import os
# 删除文件夹文件
def delete_files_in_directory(directory):
# 遍历目录中的所有文件和子目录
deleted_count = 0 # 初始化计数器
for filename in os.listdir(directory):
file_path = os.path.join(directory, filename)
try:
# 如果是文件,则删除
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
deleted_count += 1
elif os.path.isdir(file_path):
# 这里我们不删除子目录,只删除文件
# 如果需要删除空目录,可以在此处添加逻辑
pass
except Exception as e:
print(f"Error while deleting {file_path}: {e}")
return deleted_count
# 要删除的文件所处文件夹
directory_to_clean = 'E:/test'
# 定时时间(3秒)
interval = 3000
# QT逻辑部分
class Ui_MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 创建一个QTimer实例
self.timer = QTimer(self)
# 连接QTimer的timeout信号到另一个槽函数
self.timer.timeout.connect(self.check_and_delete_files)
# 布局设置
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(331, 231)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setGeometry(QtCore.QRect(50, 30, 241, 121))
self.textBrowser.setObjectName("textBrowser")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(10, 30, 72, 15))
self.label_2.setObjectName("label_2")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(50, 170, 93, 28))
self.pushButton.clicked.connect(self.on_pushButton_clicked) # 绑定点击事件
self.pushButton.setObjectName("pushButton")
self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_3.setGeometry(QtCore.QRect(200, 170, 93, 28))
self.pushButton_3.setObjectName("pushButton_3")
self.pushButton_3.clicked.connect(self.on_pushButton3_clicked) # 绑定点击事件
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
# 按钮标签
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "定时任务"))
self.label_2.setText(_translate("MainWindow", "记录:"))
self.pushButton.setText(_translate("MainWindow", "启动"))
self.pushButton_3.setText(_translate("MainWindow", "退出"))
# 点击启动按钮逻辑
def on_pushButton_clicked(self):
# 当pushButton被点击时执行的代码
if self.pushButton.text() == '启动':
self.textBrowser.append("定时任务已启动......")
self.pushButton.setText('暂停')
# 开始定时器,例如每3秒触发一次
self.timer.start(interval)
else:
self.textBrowser.append("定时任务已暂停......")
self.pushButton.setText('启动')
self.timer.stop() # 停止定时器
# 点击退出按钮逻辑
def on_pushButton3_clicked(self):
# 当pushButton_3被点击时执行的代码
QtWidgets.QApplication.quit() # 退出应用程序
# 插槽,定时任务
@pyqtSlot()
def check_and_delete_files(self):
if not os.path.exists(directory_to_clean): # 没有该文件夹
self.textBrowser.append(f"<span style='color:red;'>文件夹:{directory_to_clean}不存在</span>")
self.pushButton.setText('启动')
self.timer.stop() # 停止定时器
else:
deleted_count = delete_files_in_directory(directory_to_clean)
now_time = QDateTime.currentDateTime().toString('yyyy-MM-dd HH:mm:ss')
log = f'{now_time}--已删除{deleted_count}个文件'
self.textBrowser.append(log)
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())