前言
上篇博客介绍了环境的搭建与UI文件的实现,本篇博客接上篇介绍该系统的逻辑控制实现,包括文件的上传、下载、查看、删除,以及文件链接的 markdown 格式化。
代码实现
新建 appUI.py
文件。
在这里,需要用到QT控件,系统时间调用,以及之前编辑的UI文件。首先导入python
包
from PyQt5 import QtWidgets
from aliyunOSS import Ui_MainWindow
from aliyunManage import *
import time,sys
操作类实现
这里需要先定义一个类MainWindow
。名字必须与之前文件的Ui_MainWindow
窗体接口名字一样。
该类继承了QtWidgets
中的QMainWindow
类与aliyunOSS
中的 Ui_MainWindow
类,代码是这样的:
class MainWindow(QtWidgets.QMainWindow,Ui_MainWindow):
类的初始化
这里实现了窗口的初始化 setupUi
。获取系统时间,并存为 年-月-日 格式,获取时间的原因是后面根据日期自动生成上传文件夹的名字。用户信息的显示 fillUserState
。
def __init__(self, parent=None):
super(MainWindow,self).__init__(parent)
self.setupUi(self)
self.targetFoldText.setText(time.strftime("%Y-%m-%d", time.localtime(time.time())))
self.fillUserState()
用户属性界面
将用户信息填入文本框:
def fillUserState(self):
self.jsondata=jsonOp()
self.AccessKeyId.setText(self.jsondata.data['AccessKeyId'])
self.AccessKeySecret.setText(self.jsondata.data['AccessKeySecret'])
self.bucket.setText(self.jsondata.data['bucket'])
self.EndPoint.setText(self.jsondata.data['EndPoint'])
响应用户属性界面的 保存 按钮,修改用户信息并写入json
文件:
def changeUser(self):
self.jsondata.data['AccessKeyId']=self.AccessKeyId.toPlainText()
self.jsondata.data['AccessKeySecret']=self.AccessKeySecret.toPlainText()
self.jsondata.data['bucket']=self.bucket.toPlainText()
self.jsondata.data['EndPoint']=self.EndPoint.toPlainText()
self.jsondata.write()
查看文件界面
响应 刷新 按钮,显示云端存储文件:
def getFile(self):
self.ossItemsText.clear()
oss=OSSOp()
files=oss.showfile()
for file in files:
self.ossItemsText.addItem(file)
响应 选中文件 按钮,点击文件显示框中文件名触发,保存当前选择文件名,同时,在外网地址文本框中显示当前文件的网络地址。
这里解释下,在阿里云中:
文件的外网地址=http://+bucket名+.+EndPoint名+/+上传文件名
其中上传的文件名是包括文件路径名的。
def OSSfileSelect(self):
self.OSSItemSelect=self.ossItemsText.currentItem()
self.OSSFileAddrText.clear()
self.OSSFileAddrText.insertPlainText('http://'+self.jsondata.data['bucket']+'.'+self.jsondata.data['EndPoint']+'/'+self.OSSItemSelect.text())
响应 markdown 按钮,将文件外网地址转为 markdown 的图片插入格式:
def showMarkdown(self):
name=self.OSSFileAddrText.toPlainText()
self.OSSFileAddrText.clear()
self.OSSFileAddrText.insertPlainText('![]('+name+')')
响应 删除文件 按钮,先检查是否选中文件,否则弹出 未选中文件 窗口,删除成功后刷新文件显示框:
def deleteFile(self):
oss=OSSOp()
try:
if len(self.OSSItemSelect.text()):
if oss.deletefile(self.OSSItemSelect.text())==True:
self.getFile()
else:
QtWidgets.QMessageBox.information(None, 'Message', '未选中文件',QtWidgets.QMessageBox.Yes)
except AttributeError as e:
QtWidgets.QMessageBox.information(None, 'Message', '未选中文件',QtWidgets.QMessageBox.Yes)
响应 下载文件 按钮,这里需要先点击文件显示框中的文件,否则会弹出未选中文件的提示:
def downloadFile(self):
oss=OSSOp()
try:
if len(self.OSSItemSelect.text()):
file_name,path = QtWidgets.QFileDialog.getSaveFileName(self,"save file","" ,"all files(*.*)")
if oss.downloadfile(self.OSSItemSelect.text(),file_name)==True:
QtWidgets.QMessageBox.information(None, 'Message', '下载成功',QtWidgets.QMessageBox.Yes)
else:
QtWidgets.QMessageBox.information(None, 'Message', '未选中文件',QtWidgets.QMessageBox.Yes)
except AttributeError as e:
QtWidgets.QMessageBox.information(None, 'Message', '未选中文件',QtWidgets.QMessageBox.Yes)
上传文件界面
响应 选择文件 按钮,调用系统的文件浏览器,选中文件后会在右方文本框显示所选文件。
def selectFile(self):
files, filetype = QtWidgets.QFileDialog.getOpenFileNames(None,"文件选择","","All Files (*)")
self.selectText.clear()
for name in files:
self.selectText.insertPlainText(name+'\n')
这里使用了 QtWidgets.QFileDialog.getOpenFileNames
可选择多个文件。
这里列下关于QT的文件选择函数
函数名 | 用处 |
---|---|
getExistingDirectory | 选择文件夹 |
getOpenFileName | 选择单个文件 |
getOpenFileNames | 选择多个文件 |
getSaveFileName | 保存文件 |
具体用法,以 getOpenFileNames
为例,其他函数一样,
files, filetype = QtWidgets.QFileDialog.getOpenFileNames(None,"文件选择","","All Files (*)")
第一个参数是父窗口名,直接用None,表示无父窗口;
第二个参数是窗口的名字,任写;
第三个是打开的文件浏览器路径,空 表示打开上次打开的文件夹,若是第一次打开则打开程序所在文件夹;
第四个表示文件打开的类型,All Files(*)表示所有类型。
响应 上传文件 按钮:
def uploadFile(self):
oss=OSSOp()
files=self.selectText.toPlainText()
self.targetFileAddrText.clear()
if len(files)!=0:
fileName=files.split('\n')[:-1]
for file in fileName:
result=file.split('/')
res=result[len(result)-1]
fold=self.targetFoldText.toPlainText()
if fold!='':
fold+='/'
if oss.putfile(fold+res,file)==False:
QtWidgets.QMessageBox.information(None, 'Message', '文件'+res+'上传失败',QtWidgets.QMessageBox.Yes)
return
else:
self.targetFileAddrText.insertPlainText('http://'+self.jsondata.data['bucket']+'.'+self.jsondata.data['EndPoint']+'/'+fold+res+'\n')
QtWidgets.QMessageBox.information(None, 'Message', '文件上传成功',QtWidgets.QMessageBox.Yes)
else:
QtWidgets.QMessageBox.information(None, 'Message', '未选中文件',QtWidgets.QMessageBox.Yes)
由于这里是可以支持文件多选的,先利用
files.split('\n')[:-1]
以 \n
为分割符分割字符串,这里得到的最后一个字符串是空字符串,使用[:-1]
舍弃。
得到的文件名是包括路径的,我们需要获取单独的文件名,继续利用file.split(‘/‘)分割字符,字符串集合的最后一个是文件名。
将目标文件文本框内容与文件名组合成上传文件名,使用 oss.putfile
函数上传。
上传文件地址markdown格式化:
def uploadMarkdown(self):
names=self.targetFileAddrText.toPlainText()
self.targetFileAddrText.clear()
if len(names)!=0:
name=names.split('\n')[:-1]
for item in name:
self.targetFileAddrText.insertPlainText('![]('+item+')\n')
主函数
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
打包成 EXE 文件
这里一定要先选中 appUI.py
文件,这个是启动文件,然后点击 工具->pyinstaller,等待完成即可,然后在项目文件夹中会生成 build 和dist 两个文件夹。其中,build 目录是 pyinstaller 存储临时文件的目录,可以直接删除。dist 文件夹存放生成的 exe 文件,将 data.json
文件拷入,即可运行了。
这里在使用 pyinstaller 还遇到一个错误,是在 pyinstaller输出窗口报错:
module 'enum' has no attribute 'IntFlag'?
查阅 stack overflow 得到了解决方案,原因是使用了 enum34
这个库,而这个库在 python3.4 以上的版本已经弃用了,直接用pip卸载:
pip uninstall enum34
总结
这个管理系统算是我用python+qt做的第一个界面程序,由于也是对qt不熟悉,功能基本都是拼凑出来的,bug这东西,当然一大堆了。功能也不够完善,目前只是在写 markdown 博客时上传云端图片使用。
好在各个模块的功能是相对独立的,后续还有什么功能的需要的话可以直接在里面添加就行。