项目地址:https://github.com/pikeduo/TXTReader
PyQt5中文手册:https://maicss.gitbook.io/pyqt-chinese-tutoral/pyqt5/
QtDesigner学习地址:https://youcans.blog.csdn.net/article/details/120640342
一、保存设置
为了保存用户的设置,我们可以使用QSettings类来保存设置。首先新建一个cofig.ini文件。
[DEFAULT]
下的内容代表应用的默认设置,在用户恢复默认设置时使用。[FILE]
下的用户当前对文件的设置。
每次打开文件时,初始化设置。
class MyMainWindow(QMainWindow, Ui_MainWindow): # 继承 QMainWindow 类和 Ui_MainWindow 界面类
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent) # 初始化父类
self.setupUi(self) # 继承 Ui_MainWindow 界面类
# 加载设置
self.init_info()
# 初始化设置
def init_info(self):
self.setting = QtCore.QSettings("./config.ini", QtCore.QSettings.IniFormat) # 配置文件
self.setting.setIniCodec('utf-8') # 设置配置文件的编码格式
self.cur_file = self.setting.value("FILE/file") # 目前打开的文件
self.last_files = self.setting.value("FILE/files") # 最近打开的文件
if not self.last_files:
self.last_files = []
因为last_files是一个数组文件,所以当它为空时,要初始化为空数组。
然后在退出窗口时要保存配置文件。
# 保存设置
def save_info(self):
self.setting.setValue("FILE/file", self.cur_file)
self.setting.setValue("FILE/files", self.last_files)
至于退出时的操作,我们之后再讲。
二、打开文件
为打开文件这个菜单栏设置一个触发器。
# 打开文件
self.actionfile.triggered.connect(self.open_file)
open_file
是自建的函数,当点击打开文件时触发。
# 打开文件
def open_file(self):
# 弹出QFileDialog窗口。getOpenFileName()方法的第一个参数是说明文字,
# 第二个参数是默认打开的文件夹路径。默认情况下显示所有类型的文件。
if not self.cur_file:
path = '/'
else:
path = self.cur_file
fname = QFileDialog.getOpenFileName(self, '打开文件', path, filter='*.txt')
self.load_file(fname[0])
弹出一个文件浏览器,首先会判断用户是否打开过文件,如果没有则设置文件浏览器的打开路径为当前目录,否则打开文件所在的目录,之后导入文件。
def load_file(self, file):
# 文件不为空
if file:
try:
# 更改目前打开的文件
self.cur_file = file
self.filename = file.split('/')[-1].split('.')[0]
# 将打开的文件添加到最近文件中去
# 如果文件存在,则要更改文件的打开顺序
if file in self.last_files:
self.last_files.remove(file)
self.last_files.append(file)
# 只存储最近打开的五本书籍
if len(self.last_files) > 5:
self.last_files.pop(0)
# 获取文件的编码格式
encodings = self.get_encoding(file)
with open(file, 'r', encoding=encodings) as f:
txt = f.read()
self.textBrowser.setText(txt)
self.textBrowser.setStatusTip(self.filename)
except:
self.show_msg('文件不存在或者错误!')
else: # 文件为空,说明没有选择文件
self.show_msg('您没有选择文件!')
因为事先不知道文本的编码格式,打开文件时会报错,所以需要使用get_encoding
函数来获取文本编码。
# 获取文件编码类型
def get_encoding(self, file):
# 二进制方式读取,获取字节数据,检测类型
with open(file, 'rb') as f:
return cchardet.detect(f.read())['encoding']
show_msg
是一个消息提示框,打开文件出错时会弹出弹窗。
打开文件的功能就完成了。
不过目前我们还没有保存我们的设置,在关闭窗口时,我们弹出一个确认窗口,并且保存我们的配置。
# 关闭窗口时更新窗口大小
def closeEvent(self, event):
result = QMessageBox.question(self, "关闭应用", "确定关闭应用?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if result == QMessageBox.Yes:
# 在关闭窗口时保存设置
self.save_info()
event.accept()
QMainWindow.closeEvent(self, event)
else:
event.ignore()
重写了关闭事件,同时在每次打开应用时,打开之前已经打开的文件。
# 如果之前打开过文件,则直接加载文件
if self.cur_file:
self.load_file(self.cur_file)
目前代码如下。
import ctypes
import sys
import cchardet as cchardet
from PyQt5 import QtCore
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox
from QtDesigner.UI.UIReader import Ui_MainWindow
# 加上这段话,在运行程序时,设置的窗口图标才会出现
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
class MyMainWindow(QMainWindow, Ui_MainWindow): # 继承 QMainWindow 类和 Ui_MainWindow 界面类
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent) # 初始化父类
self.setupUi(self) # 继承 Ui_MainWindow 界面类
# 加载设置
self.init_info()
# 如果之前打开过文件,则直接加载文件
if self.cur_file:
self.load_file(self.cur_file)
# 打开文件
self.actionfile.triggered.connect(self.open_file)
# 打开文件
def open_file(self):
# 弹出QFileDialog窗口。getOpenFileName()方法的第一个参数是说明文字,
# 第二个参数是默认打开的文件夹路径。默认情况下显示所有类型的文件。
if not self.cur_file:
path = '/'
else:
path = self.cur_file
fname = QFileDialog.getOpenFileName(self, '打开文件', path, filter='*.txt')
self.load_file(fname[0])
def load_file(self, file):
# 文件不为空
if file:
try:
# 更改目前打开的文件
self.cur_file = file
self.filename = file.split('/')[-1].split('.')[0]
# 将打开的文件添加到最近文件中去
# 如果文件存在,则要更改文件的打开顺序
if file in self.last_files:
self.last_files.remove(file)
self.last_files.append(file)
# 只存储最近打开的五本书籍
if len(self.last_files) > 5:
self.last_files.pop(0)
# 获取文件的编码格式
encodings = self.get_encoding(file)
with open(file, 'r', encoding=encodings) as f:
txt = f.read()
self.textBrowser.setText(txt)
self.textBrowser.setStatusTip(self.filename)
except:
self.show_msg('文件不存在或者错误!')
else: # 文件为空,说明没有选择文件
self.show_msg('您没有选择文件!')
def show_msg(self, msg):
# 后两项分别为按钮(以|隔开,共有7种按钮类型,见示例后)、默认按钮(省略则默认为第一个按钮)
reply = QMessageBox.information(self, "提示", msg, QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes)
# 获取文件编码类型
def get_encoding(self, file):
# 二进制方式读取,获取字节数据,检测类型
with open(file, 'rb') as f:
return cchardet.detect(f.read())['encoding']
# 初始化设置
def init_info(self):
self.setting = QtCore.QSettings("./config.ini", QtCore.QSettings.IniFormat) # 配置文件
self.setting.setIniCodec('utf-8') # 设置配置文件的编码格式
self.cur_file = self.setting.value("FILE/file") # 目前打开的文件
self.last_files = self.setting.value("FILE/files") # 最近打开的文件
if not self.last_files:
self.last_files = []
# 保存设置
def save_info(self):
self.setting.setValue("FILE/file", self.cur_file)
self.setting.setValue("FILE/files", self.last_files)
# 关闭窗口时更新窗口大小
def closeEvent(self, event):
result = QMessageBox.question(self, "关闭应用", "确定关闭应用?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if result == QMessageBox.Yes:
# 在关闭窗口时保存设置
self.save_info()
event.accept()
QMainWindow.closeEvent(self, event)
else:
event.ignore()
if __name__ == '__main__':
app = QApplication(sys.argv) # 在 QApplication 方法中使用,创建应用程序对象
myWin = MyMainWindow() # 实例化 MyMainWindow 类,创建主窗口
myWin.show() # 在桌面显示控件 myWin
sys.exit(app.exec_()) # 结束进程,退出程序
三、浏览最近打开的文件
菜单栏里我们已经添加了打开最近文件的功能,现在需要为其添加子动作显示最近打开的文件,并且设置触发器。
# 显示最近的文件
def show_last_file(self):
# 每次绘制时将之前的清空
self.lastfile.clear()
_translate = QtCore.QCoreApplication.translate
for i, file in enumerate(self.last_files):
# 截取文件名
name = file.split('/')[-1].split('.')[0]
# 添加action
action = QtWidgets.QAction(self)
action.setObjectName(f'file{i}') # 设置对象名
self.lastfile.addAction(action) # 添加到菜单栏中
action.setText(_translate("MyMainWindow", name)) # 添加到主窗口,且设置text
action.triggered.connect(self.open_last_file) # 设置触发事件
我们循环设置一个动作,编辑其对象名称为文件名,并且添加到菜单栏中,设置触发器。
# 打开最近的文件
def open_last_file(self):
sender = self.sender().objectName() # 获取当前信号 sender
# 根据我们设置的对象名,截取字符,然后从配置文件寻找文件路径
self.load_file(self.last_files[int(sender[-1])])
根据点击第几个动作来判断打开哪个文件。
同时在每次加载文件时都重新绘制一遍最近打开的文件,将下面那段代码添加到load_file
函数中去。
# 显示最近打开的文件
self.show_last_file()
完整代码如下:
import ctypes
import sys
import cchardet as cchardet
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QFileDialog, QMessageBox
from QtDesigner.UI.UIReader import Ui_MainWindow
# 加上这段话,在运行程序时,设置的窗口图标才会出现
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
class MyMainWindow(QMainWindow, Ui_MainWindow): # 继承 QMainWindow 类和 Ui_MainWindow 界面类
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent) # 初始化父类
self.setupUi(self) # 继承 Ui_MainWindow 界面类
# 加载设置
self.init_info()
# 如果之前打开过文件,则直接加载文件
if self.cur_file:
self.load_file(self.cur_file)
# 打开文件
self.actionfile.triggered.connect(self.open_file)
# 打开文件
def open_file(self):
# 弹出QFileDialog窗口。getOpenFileName()方法的第一个参数是说明文字,
# 第二个参数是默认打开的文件夹路径。默认情况下显示所有类型的文件。
if not self.cur_file:
path = '/'
else:
path = self.cur_file
fname = QFileDialog.getOpenFileName(self, '打开文件', path, filter='*.txt')
self.load_file(fname[0])
# 显示最近的文件
def show_last_file(self):
# 每次绘制时将之前的清空
self.lastfile.clear()
_translate = QtCore.QCoreApplication.translate
for i, file in enumerate(self.last_files):
# 截取文件名
name = file.split('/')[-1].split('.')[0]
# 添加action
action = QtWidgets.QAction(self)
action.setObjectName(f'file{i}') # 设置对象名
self.lastfile.addAction(action) # 添加到菜单栏中
action.setText(_translate("MyMainWindow", name)) # 添加到主窗口,且设置text
action.triggered.connect(self.open_last_file) # 设置触发事件
# 打开最近的文件
def open_last_file(self):
sender = self.sender().objectName() # 获取当前信号 sender
# 根据我们设置的对象名,截取字符,然后从配置文件寻找文件路径
self.load_file(self.last_files[int(sender[-1])])
def load_file(self, file):
# 文件不为空
if file:
try:
# 更改目前打开的文件
self.cur_file = file
self.filename = file.split('/')[-1].split('.')[0]
# 将打开的文件添加到最近文件中去
# 如果文件存在,则要更改文件的打开顺序
if file in self.last_files:
self.last_files.remove(file)
self.last_files.append(file)
# 只存储最近打开的五本书籍
if len(self.last_files) > 5:
self.last_files.pop(0)
# 获取文件的编码格式
encodings = self.get_encoding(file)
with open(file, 'r', encoding=encodings) as f:
txt = f.read()
self.textBrowser.setText(txt)
self.textBrowser.setStatusTip(self.filename)
# 显示最近打开的文件
self.show_last_file()
except:
self.show_msg('文件不存在或者错误!')
else: # 文件为空,说明没有选择文件
self.show_msg('您没有选择文件!')
def show_msg(self, msg):
# 后两项分别为按钮(以|隔开,共有7种按钮类型,见示例后)、默认按钮(省略则默认为第一个按钮)
reply = QMessageBox.information(self, "提示", msg, QMessageBox.Yes | QMessageBox.No,
QMessageBox.Yes)
# 获取文件编码类型
def get_encoding(self, file):
# 二进制方式读取,获取字节数据,检测类型
with open(file, 'rb') as f:
return cchardet.detect(f.read())['encoding']
# 初始化设置
def init_info(self):
self.setting = QtCore.QSettings("./config.ini", QtCore.QSettings.IniFormat) # 配置文件
self.setting.setIniCodec('utf-8') # 设置配置文件的编码格式
self.cur_file = self.setting.value("FILE/file") # 目前打开的文件
self.last_files = self.setting.value("FILE/files") # 最近打开的文件
if not self.last_files:
self.last_files = []
# 保存设置
def save_info(self):
self.setting.setValue("FILE/file", self.cur_file)
self.setting.setValue("FILE/files", self.last_files)
# 关闭窗口时更新窗口大小
def closeEvent(self, event):
result = QMessageBox.question(self, "关闭应用", "确定关闭应用?",
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if result == QMessageBox.Yes:
# 在关闭窗口时保存设置
self.save_info()
event.accept()
QMainWindow.closeEvent(self, event)
else:
event.ignore()
if __name__ == '__main__':
app = QApplication(sys.argv) # 在 QApplication 方法中使用,创建应用程序对象
myWin = MyMainWindow() # 实例化 MyMainWindow 类,创建主窗口
myWin.show() # 在桌面显示控件 myWin
sys.exit(app.exec_()) # 结束进程,退出程序
下期我们讲怎么分割章节,切换章节内容。
标签:files,文件,last,Python,self,pyqt5,file,打开 From: https://www.cnblogs.com/pikeduo/p/17037172.html