首页 > 编程语言 >使用Python库pyqt5制作TXT阅读器(二)-------打开文件和浏览最近的文件

使用Python库pyqt5制作TXT阅读器(二)-------打开文件和浏览最近的文件

时间:2023-01-09 15:23:06浏览次数:59  
标签:files 文件 last Python self pyqt5 file 打开

项目地址: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

相关文章

  • Python安装libsvm
    最近在学习机器学习,听的是浙大胡浩基老师的课。胡老师用的是MatLab,我平时用Python比较多,在网上找Python安装libsvm的教程发现比较少,花了几个小时终于成功安装了libsvm,现......
  • linux scp文件分发脚本
    说明:集群节点之间文件、目录分发同步脚本将本节点指定目录的文件同步到对应集群所有节点的相同位置fdir为文件的绝对路径,用于指定集群节点中目标目录路径#!/bin/bash......
  • git代码仓sourcetree忽略.xcuserstate或.xcscheme等文件设置
    首先编辑.gitignore文件如下然后将我们想忽略的文件加上然后终端输入如下代码cd项目路径gitrm-r--cached.gitadd.gitcommit-m''"之后重启source......
  • B/S超大文件上传
    ​ javaweb上传文件上传文件的jsp中的部分上传文件同样可以使用form表单向后端发请求,也可以使用ajax向后端发请求    1.通过form表单向后端发送请求     ......
  • HP Unix 挂载 ISO 文件的两种方法:
    有两种方法: 1、如果iso文件小于2GB,可以用如下方式: #/usr/sbin/pfs_mountd&#/usr/sbin/pfsd&#pfs_mount-tiso9660/data/hpux_v11.11.iso/mnt/temp#cd/mnt/t......
  • Python 基础实战
    1.概述本节实现一个文件管理程序,该程序会使用到如下知识点:函数面向对象采用面向对象的程序设计方法对数据建模异常处理使用异常处理和文件相关的错误,例如文件不存在模块......
  • java文件夹和文件
    本文主要讲述java如何创建文件夹和文件题目:指定路径,判断当前路径是否有目标文件夹,如果没有,则创建;如果有,在目标文件夹下创建目标文件【txt文件】,并使用转换流+处理流写入......
  • python ssh链接Mysql数据库
    fromsshtunnelimportSSHTunnelForwarderimporttime,datetime,pymysql,json,requestsdefssh_mysql(sql,method):#SSH信息ssh_ip=''ssh_port=22......
  • 01notepad++如何比较两个文件内容
    下面介绍,通过在NotePad中下载安装Compare插件,可以比较两个文件内容。(推荐学习:notepad++)打开NotePad,点击工具栏上的【插件】–》PluginManager—》ShowPluginManage......
  • python 每天一个知识点 第四天
    字符串:一,字符串的定义:使用单引号’你可以用单引号指示字符串,就如同’这是一句话’这样str='这是一句话'print(str)使用双引号"在双引号中的字符串与单引......