PyQt5桌面应用开发(6):文件对话框

news2024/11/24 16:21:02

本文目录

  • PyQt5桌面应用系列
  • 介绍
  • QFileDialog的静态接口
    • QFileDialog的对象接口
  • 示例
  • 结论
  • 后记

PyQt5桌面应用系列

  • PyQt5桌面应用开发(1):需求分析
  • PyQt5桌面应用开发(2):事件循环
  • PyQt5桌面应用开发(3):并行设计
  • PyQt5桌面应用开发(4):界面设计
  • PyQt5桌面应用开发(5):对话框
  • PyQt5桌面应用开发(6):文件对话框
  • PyQt5桌面应用开发(7):文本编辑+语法高亮与行号

介绍

读入和写文件是一个GUI程序的常用操作。前者导入需要处理的数据,后者把数据输出到硬盘上后期使用。PyQt5提供了PyQt5.QtWidgets.QFileDialog类来完成常用的文件打开、文件存储的功能。

这个类有两个接口形式。第一种形式采用静态函数,调用的方式就是QFileDialog.method(),比如QFileDialog.getOpenFileName()。第二种形式需要先创建一个QFileDialog对象,然后调用对象的method()方法,比如QFileDialog().getOpenFileName()

QFileDialog的静态接口

方便使用的静态函数包括下面的函数:

    def getExistingDirectory(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getExistingDirectory(parent: typing.Optional[QWidget] = None, caption: str = '', directory: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = QFileDialog.ShowDirsOnly) -> str """
        pass

    def getExistingDirectoryUrl(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getExistingDirectoryUrl(parent: typing.Optional[QWidget] = None, caption: str = '', directory: QUrl = QUrl(), options: Union[QFileDialog.Options, QFileDialog.Option] = QFileDialog.ShowDirsOnly, supportedSchemes: Iterable[str] = []) -> QUrl """
        pass

    def getOpenFileName(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getOpenFileName(parent: typing.Optional[QWidget] = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0) -> Tuple[str, str] """
        pass

    def getOpenFileNames(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getOpenFileNames(parent: typing.Optional[QWidget] = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0) -> Tuple[List[str], str] """
        pass

    def getOpenFileUrl(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getOpenFileUrl(parent: typing.Optional[QWidget] = None, caption: str = '', directory: QUrl = QUrl(), filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0, supportedSchemes: Iterable[str] = []) -> Tuple[QUrl, str] """
        pass

    def getOpenFileUrls(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getOpenFileUrls(parent: typing.Optional[QWidget] = None, caption: str = '', directory: QUrl = QUrl(), filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0, supportedSchemes: Iterable[str] = []) -> Tuple[List[QUrl], str] """
        pass

    def getSaveFileName(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getSaveFileName(parent: typing.Optional[QWidget] = None, caption: str = '', directory: str = '', filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0) -> Tuple[str, str] """
        pass

    def getSaveFileUrl(self, parent, QWidget=None, *args, **kwargs): # real signature unknown; NOTE: unreliably restored from __doc__ 
        """ getSaveFileUrl(parent: typing.Optional[QWidget] = None, caption: str = '', directory: QUrl = QUrl(), filter: str = '', initialFilter: str = '', options: Union[QFileDialog.Options, QFileDialog.Option] = 0, supportedSchemes: Iterable[str] = []) -> Tuple[QUrl, str] """
        pass

可以很方便的打开目录、多文件、单文件,保存文件。函数的返回值第一就是文件的路径,第二个是文件的类型。如果采用Url的形式,则可以打开类似于PyQt5.QtCore.QUrl('file:///C:/Users/User/qchen/pyqt5/chart1.py')的形式,这种方式应该还可以很方便的打开ftp等形式的文件。

QFileDialog的对象接口

采用对象的接口也非常直观。

  1. 创建一个QFileDialog对象;
  2. 调用QFileDialog对象的setWindowTitle()方法设置标题;
  3. 调用QFileDialog对象的setDirectory()方法设置默认打开的目录;
  4. 调用QFileDialog对象的setNameFilter()方法设置文件过滤器;
  5. 调用QFileDialog对象的setFileMode()方法设置文件模式;
  6. 调用QFileDialog对象的setViewMode()方法设置视图模式;
  7. 调用QFileDialog对象的setOption()方法设置对话框的选项;
  8. 调用QFileDialog对象的open()方法打开对话框;
  9. 调用QFileDialog对象的selectedFiles()方法获取选中的文件,或者调用QFileDialog对象的selectedUrl()方法获取选中的文件的Url。

示例

下面的示例代码演示了如何使用QFileDialog类。

import sys
from functools import partial

from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QAction, QTextEdit, QFileDialog, QWidget, QStatusBar, \
    QToolBar, QStyle

current_file: str = None


def open_file_func(parent: QWidget, content: QTextEdit, checked: bool):
    try:
        file, current_filter = QFileDialog.getOpenFileName(parent,
                                                           "Open File",
                                                           ".",
                                                           "Text Files (*.txt);;Python Files (*.py);;Markdown Files ("
                                                           "*.md)")

        with open(file, "r", encoding="utf-8") as fid:
            content.setText(fid.read())
            global current_file
            current_file = file
            if isinstance(parent, QMainWindow):
                parent: QMainWindow
                parent.statusBar().showMessage(f"Opened {file}")
                parent.setWindowTitle(file)
    except Exception as e:
        content.setText(f"<b style='color:#FF0000'>{str(e)}</b>")
        current_file = None


def save_file_func(parent: QWidget, content: QTextEdit, checked: bool):
    try:
        global current_file
        if current_file is None:
            save_as_file_func(parent, content, checked)
            return
        with open(current_file, "w", encoding="utf-8") as fid:
            fid.write(content.toPlainText())
            if isinstance(parent, QMainWindow):
                parent: QMainWindow
                parent.statusBar().showMessage(f"Saved {current_file}")
                parent.setWindowTitle(current_file)
    except Exception as e:
        content.setText(f"<b style='color:#FF0000'>{str(e)}</b>")
        current_file = None


def save_as_file_func(parent: QWidget, content: QTextEdit, checked: bool):
    try:
        file, current_filter = QFileDialog.getSaveFileName(parent,
                                                           "Open File",
                                                           ".",
                                                           "Text Files (*.txt);;Python Files (*.py);;Markdown Files ("
                                                           "*.md)")
        with open(file, "w", encoding="utf-8") as fid:
            fid.write(content.toPlainText())
            global current_file
            current_file = file
            if isinstance(parent, QMainWindow):
                parent: QMainWindow
                parent.statusBar().showMessage(f"Saved {file}")
                parent.setWindowTitle(file)
    except Exception as e:
        content.setText(f"<b style='color:#FF0000'>{str(e)}</b>")
        current_file = None


def file_edited(parent: QMainWindow):
    parent: QMainWindow
    if current_file == parent.windowTitle():
        parent.setWindowTitle(f"{current_file}*")


if __name__ == '__main__':
    app = QApplication(sys.argv)

    mw = QMainWindow()
    content_edit = QTextEdit(mw)
    menu = QMenuBar(mw)
    sb = QStatusBar(mw)
    tb = QToolBar(mw)

    content_edit.textChanged.connect(partial(file_edited, mw))

    mw.setMenuBar(menu)
    mw.setCentralWidget(content_edit)
    mw.setStatusBar(sb)
    mw.addToolBar(tb)

    file_menu = menu.addMenu("&File")

    open_file = QAction("Open", mw)
    open_file.setShortcut("Ctrl+O")
    open_file.setIcon(mw.style().standardIcon(QStyle.SP_DialogOpenButton))
    open_file.triggered.connect(partial(open_file_func, mw, content_edit))

    save_as_file = QAction("Save as", mw)
    save_as_file.setShortcut("Ctrl+Shift+S")
    save_as_file.setIcon(QIcon("sa.png"))
    save_as_file.triggered.connect(partial(save_as_file_func, mw, content_edit))

    save_file = QAction("Save", mw)
    save_file.setShortcut("Ctrl+S")
    save_file.setIcon(mw.style().standardIcon(QStyle.SP_DialogSaveButton))
    save_file.triggered.connect(partial(save_file_func, mw, content_edit))

    exit_app = QAction("Exit", mw)
    exit_app.setShortcut("Ctrl+Q")
    exit_app.setIcon(mw.style().standardIcon(QStyle.SP_DialogCloseButton))
    exit_app.triggered.connect(lambda checked: mw.close())

    file_menu.addAction(open_file)
    file_menu.addAction(save_file)
    file_menu.addAction(save_as_file)
    file_menu.addSeparator()
    file_menu.addAction(exit_app)

    tb.addAction(open_file)
    tb.addAction(save_file)
    tb.addAction(save_as_file)
    tb.addAction(exit_app)

    mw.setWindowTitle("File Open Dialog")
    mw.resize(800, 600)
    mw.setWindowIcon(QIcon("icon.png"))
    mw.show()

    sys.exit(app.exec_())

这个示例实现了一个非常简单的文本编辑器。打开文件、存储文件、另存文件都实现为QAction,这个可以在菜单和工具栏上复用,还是非常方便的。

程序界面

当文件被编辑时,标题中增加*,便于保存和另存。PyQt5很好很强大啊。当然如果需要一次打开多个文件,那么这里可能需要实现一个MDIArea,这个就不是本文的重点了。

这个程序用到functools.partial,很好的帮助我们在设置QActiontriggered信号时传递参数。如果使用lambda,可能不便于捕捉参数的当地值。

程序的图标使用了部分PyQt5的标准图标,标准图标的名称用SP_xxxxQStyle中获得。

内置图标

程序本身的图标准备了两个图片文件。

程序图标
另存图标

结论

  1. QFileDialg是一个非常方便的文件选择对话框,可以用来打开文件、保存文件、选择文件夹等。
  2. QFileDialog的静态方法可以直接使用,也可以创建一个实例来使用。
  3. QFileDialog的静态方法返回的是一个元组,第一个元素是文件名,第二个元素是文件类型。

后记

当然,作为一个程序员,我对前面那个弱智玩意有很多不满意的地方,没办法,只好增加了代码语法高亮、行号、当前行高亮。

这亿点点细节就只有下次再写。
一点点细节

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/490681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux安装node_exporter

下载 Download | Prometheus 解压 tar xvzf node_exporter-1.5.0.darwin-amd64.tar.gz 解压后有三个文件&#xff0c;分别是LICENSE、node_exporter、NOTICE 将node_exporter移动到/etc下 mv mode_exporter /etc/systemd/system 创建node_exporter.service文件 touch node_exp…

基于matlab模拟雷达接收机测试信号

一、前言 本例展示了如何模拟单基地脉冲雷达的接收信号以估计目标范围。单基地雷达将发射器与接收器并置。发射器产生一个脉冲&#xff0c;该脉冲击中目标并产生接收器接收的回波。通过测量回波在时间上的位置&#xff0c;我们可以估计目标的范围。 本示例重点介绍脉冲雷达系统…

【线程安全】死锁问题及解决方案

1. 什么是死锁 比如上一次讲到 synchronized 的时候&#xff0c;一个线程&#xff0c;对同一个对象连续加锁两次&#xff0c;如果出现阻塞等待&#xff0c;代表这个锁是不可重入锁&#xff0c;这样的线程&#xff0c;也就称为死锁&#xff01; 一旦程序进入死锁了就会导致线程僵…

低代码开发重要工具:JVS列表页字段样式配置说明

列表页中&#xff0c;通常存在各种各样的样式控制&#xff0c;例如字段宽度需要可调、字段的颜色根据内容变化等&#xff0c;那么我们接下来介绍下字段的样式控制的内容以及对应的效果。 1、字段样式控制配置位置 进入列表页的 数据配置界面&#xff0c;每个字段可以有独立的配…

在外远程控制我的世界服务器 - MCSM面板【端口映射】

文章目录 概述1.MCSManager 安装2.内网穿透2.1 安装cpolar内网穿透 3. 访问公网地址4.固定公网地址4.1 保留一个二级子域名4.2 配置固定二级域名4.3 访问固定公网地址 5. 设置节点公网地址6. 固定节点公网地址6.1 保留一个固定tcp地址6.2 配置固定TCP地址 转载自远程穿透文章&a…

从零开始学习Linux运维,成为IT领域翘楚(七)

文章目录 &#x1f525;Linux下常用软件安装_JDK和Tomcat安装&#x1f525;Linux下常用软件安装_MySQL安装&#x1f525;Linux下常用软件安装_MySQL卸载 &#x1f525;Linux下常用软件安装_JDK和Tomcat安装 Jdk 安装 解压jdk安装包 tar -zxvf jdk-8u201-linux-x64.tar.gz -C/…

中国核心生态区类型及土地利用数据有哪些,如何进行获取

全国生态功能区划是在全国生态调查的基础上&#xff0c;分析区域生态特征、生态系统服务功能与生态敏感性空间分异规律&#xff0c;确定不同地域单元的主导生态功能&#xff0c;制定全国生态功能区划&#xff0c;对贯彻落实科学发展观&#xff0c;牢固树立生态文明观念&#xf…

顺序存储二叉树线索化二叉树

顺序存储二叉树&线索化二叉树 文章目录 顺序存储二叉树&线索化二叉树顺序存储二叉树介绍代码实现 线索化二叉树介绍代码实现 顺序存储二叉树 介绍 背景&#xff1a;从数据存储来看&#xff0c;数组存储方式和树的存储方式可以相互转换&#xff0c;即数组可以转换成树…

我把大厂起诉了,协商拿了2N,整理点经验心得给大家,关于离职时如何让自己利益最大化!...

离职时&#xff0c;如何让自己的利益最大化&#xff1f; 一位跟大厂仲裁&#xff0c;并通过协商拿到2n的网友分享了自己的经验心得&#xff0c;干货满满&#xff0c;下面是要点总结&#xff1a; 1.大部分裁员都是违法裁员&#xff0c;应该给2n&#xff0c;但公司不会承认&#…

排序算法 — 归并排序

文章目录 归并排序介绍从下往上的归并排序从上往下的归并排序 归并排序实现从上往下的归并排序从下往上的归并排序 归并排序的时间复杂度和稳定性归并排序时间复杂度归并排序稳定性 代码实现核心&总结 每日一道算法&#xff0c;提高脑力。第五天(时隔7天&#xff0c;终于回…

mac下用git客户端生成ssh秘钥并配置到souretree进行使用

一、使用git 生成 ssh 密钥 1、Mac 安装 git 客户端 打开终端&#xff0c;执行命令&#xff1a; $ brew install git2、执行命令 $ git config --global user.name "xxx" 你自己的名字 $ git config --global user.email "xxxxxx.com&q…

Educational-Codeforces-Round-147-Rated-for-Div-2

title: Educational Codeforces Round 147 (Rated for Div. 2) date: 2023-04-21 15:47:29 categories: AlgorithmCodeforces tags:codeforcesdiv2 Educational Codeforces Round 147 (Rated for Div. 2) A. Matching 题目大意 给你一个字符串&#xff0c;里面包含数字和?,…

Redis缓存穿透和雪崩

Redis缓存穿透和雪崩 Redis缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要害的问题&#xff0c;就是数据的一致性问题&#xff0c;从严格意义上讲&#xff0c;这个问题…

AI 工具合辑盘点(七)持续更新 之 AI 音频生成工具

AI 音频生成工具 想要不亲自录制&#xff0c;快速将文本转换为语音&#xff1f;AI 音频生成工具为你提供数千种语音选择&#xff0c;从“普通人”的声音到模仿演员、政治家或电影角色的合成声音&#xff0c;各种声音应有尽有 &#x1f5e3; AI 音频生成工具可用于创建商业用途…

模糊PID模糊控制(清晰化方法梯形图实现)

模糊PID的模糊化请参看下面的博客文章: 博途PLC模糊PID三角隶属度函数指令(含Matlab仿真)_plc 模糊pid_RXXW_Dor的博客-CSDN博客三角隶属度函数FC,我们采用兼容C99标准的函数返回值写法,在FB里调用会更加直观,下面给大家具体讲解代码。常规写法的隶属度函数FC可以参看下…

Python小姿势 - Python中的列表推导式

Python中的列表推导式 Python中的列表推导式是一种很好的创建列表的方式。它允许你将一个操作应用于列表中的每个元素&#xff0c;并将结果放入一个新的列表中。 例如&#xff0c;假设你有一个包含数字的列表&#xff0c;但是你想将每个数字都乘以2&#xff0c;并将结果放入一个…

第三十二章 Unity Mecanim动画系统(上)

在上一章节中&#xff0c;我们介绍了Unity的旧版动画系统&#xff0c;本章节来介绍新版的Mecanim动画系统。新版的Mecanim动画系统实际是对旧版动画系统的升级。新版的Mecanim动画系统仍然是建立在动画片段的基础上的&#xff0c;只不过它给我们提供了一个可视化的窗口来编辑动…

服务攻防-数据库安全-服务应用的安全问题以及测试流程-MysqlHadoop未授权访问RCE-漏洞复现

目录 一、服务应用的安全问题 1、配置不当——未授权访问 2、安全机制——特定安全漏洞 3、安全机制——弱口令爆破攻击 二、服务应用的安全测试思路 1、判断服务是否开放 2、判断服务类型 3、判断利用方式 三、Mysql-未授权访问-CVE-2012-2122 利用 1、漏洞概述 2、…

Detours HOOK

参考文本 如何使用Detours库进行DLL注入&#xff0c;拦截API - 知乎 (zhihu.com) 解决‘nmake‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。_nmake 不是内部或外部命令,也不是可运行的程序 或批处理文件。_AI浩的博客-CSDN博客 Detours使用方法&#xff0c;简单…

五音不全?手把手教你用自己声音唱任何歌;最详细的Auto-GPT整理;4月AI绘画模型推荐;HayoAI平台简直太酷了 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『ChatGPT Code Interpreter Magic』魔法&#xff01;离谱&#xff01;正在怀疑人生… OpenAI 近期面向部分用户发放了 Code Interp…