PyQt5 打开文件对话框和文本编辑器

PyQt5 打开文件对话框和文本编辑器

一个小型文本编辑器是很适合作为第一个 PyQt5 项目的练习,因为它会用到几个常见的 Qt 概念:主窗口、中心组件、菜单、动作以及文件对话框。

下面的示例创建了一个简单的编辑器,可以打开文本文件,在 QTextEdit 中显示内容,编辑内容,并将其保存回磁盘。

示例

import sys

from PyQt5.QtWidgets import (
    QAction,
    QApplication,
    QFileDialog,
    QMainWindow,
    QMessageBox,
    QTextEdit,
)


class TextEditor(QMainWindow):
    def __init__(self):
        super().__init__()

        self.current_file = None
        self.editor = QTextEdit()
        self.setCentralWidget(self.editor)

        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("PyQt5 Text Editor")
        self.resize(800, 600)

        open_action = QAction("Open", self)
        open_action.setShortcut("Ctrl+O")
        open_action.triggered.connect(self.open_file)

        save_action = QAction("Save", self)
        save_action.setShortcut("Ctrl+S")
        save_action.triggered.connect(self.save_file)

        save_as_action = QAction("Save As", self)
        save_as_action.setShortcut("Ctrl+Shift+S")
        save_as_action.triggered.connect(self.save_file_as)

        exit_action = QAction("Exit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)

        file_menu = self.menuBar().addMenu("File")
        file_menu.addAction(open_action)
        file_menu.addAction(save_action)
        file_menu.addAction(save_as_action)
        file_menu.addSeparator()
        file_menu.addAction(exit_action)

    def open_file(self):
        file_name, _ = QFileDialog.getOpenFileName(
            self,
            "Open File",
            "",
            "Text Files (*.txt);;Python Files (*.py);;All Files (*)",
        )

        if not file_name:
            return

        try:
            with open(file_name, "r", encoding="utf-8") as file:
                self.editor.setPlainText(file.read())
        except OSError as error:
            QMessageBox.critical(self, "Open Error", str(error))
            return

        self.current_file = file_name
        self.setWindowTitle(f"PyQt5 Text Editor - {file_name}")

    def save_file(self):
        if self.current_file is None:
            self.save_file_as()
            return

        try:
            with open(self.current_file, "w", encoding="utf-8") as file:
                file.write(self.editor.toPlainText())
        except OSError as error:
            QMessageBox.critical(self, "Save Error", str(error))

    def save_file_as(self):
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            "Save File",
            "",
            "Text Files (*.txt);;Python Files (*.py);;All Files (*)",
        )

        if not file_name:
            return

        self.current_file = file_name
        self.save_file()
        self.setWindowTitle(f"PyQt5 Text Editor - {file_name}")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = TextEditor()
    window.show()
    sys.exit(app.exec_())

工作原理

QMainWindow 为应用提供标准的窗口结构。QTextEdit 组件通过 setCentralWidget() 放置在窗口中央。

QAction 对象用于定义菜单命令。每个动作都通过信号与槽机制连接到一个方法:

open_action.triggered.connect(self.open_file)

文件对话框会返回两个值:所选文件路径和所选过滤器。在这个示例中,只需要路径:

file_name, _ = QFileDialog.getOpenFileName(self, "Open File")

如果用户取消对话框,file_name 会为空,因此函数会直接返回,不执行任何操作。

运行程序

如果尚未安装 PyQt5,请先安装:

pip install PyQt5

将脚本保存为 text_editor.py,然后运行:

python text_editor.py

这仍然只是一个最小化的编辑器。后续可以添加一些实用功能,例如未保存更改提醒、行号、最近文件列表,以及对不同编码的支持。

Leave a Reply