当前位置: 首页 > news >正文

【QT5 Widgets示例】记事本:(三)功能实现

文章目录

  • 记事本:(三)功能实现
    • 新建文件
    • 打开文件
    • 保存文件
    • 保存为
    • 打印文件
    • 选择字体
    • 复制、剪切、粘贴、撤消和取消撤回
    • 关于和退出

记事本:(三)功能实现

下面将使用QT的信号槽机制实现界面中各项的功能。要将动作连接到槽,可以右键点击一个动作并选择“转到槽”,然后选择信号triggered()(勾选了“可选的”的动作应选择triggered(bool))。例如,右键new_file,点击转到槽:

在这里插入图片描述

这样就自动地在Notepad类中生成一个槽(slots)函数,用于响应点击new_file这一动作信号:

按照以上步骤将所有动作的转到槽:

//notepad.h
#ifndef NOTEPAD_H
#define NOTEPAD_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class Notepad; }
QT_END_NAMESPACE

class Notepad : public QMainWindow
{
    Q_OBJECT

public:
    Notepad(QWidget *parent = nullptr);
    ~Notepad();

private slots:
    void on_new_file_triggered();

    void on_open_file_triggered();

    void on_save_file_triggered();

    void on_save_as_triggered();

    void on_paste_triggered();

    void on_bolder_triggered(bool checked);

    void on_Italic_triggered(bool checked);

    void on_underline_triggered(bool checked);

    void on_font_triggered();

    void on_about_triggered();

    void on_undo_triggered();

    void on_redo_triggered();

    void on_exit_triggered();

    void on_print_triggered();

    void on_copy_triggered();

    void on_cut_triggered();

private:
    Ui::Notepad *ui;
};
#endif // NOTEPAD_H

//notepad.cpp
#include "notepad.h"
#include "ui_notepad.h"

Notepad::Notepad(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::Notepad)
{
    ui->setupUi(this);
}

Notepad::~Notepad()
{
    delete ui;
}




void Notepad::on_new_file_triggered()
{

}

void Notepad::on_open_file_triggered()
{

}

void Notepad::on_save_file_triggered()
{

}

void Notepad::on_save_as_triggered()
{

}

void Notepad::on_paste_triggered()
{

}

void Notepad::on_bolder_triggered(bool checked)
{

}

void Notepad::on_Italic_triggered(bool checked)
{

}

void Notepad::on_underline_triggered(bool checked)
{

}

void Notepad::on_font_triggered()
{

}

void Notepad::on_about_triggered()
{

}

void Notepad::on_undo_triggered()
{

}

void Notepad::on_redo_triggered()
{

}

void Notepad::on_exit_triggered()
{

}

void Notepad::on_print_triggered()
{

}

void Notepad::on_copy_triggered()
{

}

void Notepad::on_cut_triggered()
{

}

下面实现各个槽函数的功能

新建文件

首先,在 notepad.h 创建一个 私有的成员变量QString currentFile作为文本缓冲区,它存储了当前正在编辑的文件内容。

private:
    Ui::Notepad *ui;
    QString currentFile;

然后 在notepad.cpp中实现新建文件功能:

void Notepad::on_new_file_triggered()
{
    currentFile.clear(); // 清空缓冲区内容
    ui->textEdit->setText(QString());  // 清空输入框内容
}

打开文件

在notepad.cpp中包含以下头文件:

#include <QFileDialog>
#include <QMessageBox>
#include <QTextStream>

并实现打开文件功能:

void Notepad::on_open_file_triggered() {
    // 将打开一个对话框,允许用户选择一个文件。
    QString fileName = QFileDialog::getOpenFileName(this, "打开文件");
    
    // 使用用户选择的文件名创建一个QFile对象,为读写文件的接口
    QFile file(fileName);
    
    // 将当前文件名保存到成员变量currentFile中,以便后续使用
    currentFile = fileName;
    
    // 尝试以只读和文本模式打开文件
    if (!file.open(QIODevice::ReadOnly | QFile::Text)) {
        // 如果文件打开失败,显示一个警告消息框,并包含错误信息
        QMessageBox::warning(this, "警告", "无法打开此文件: " + file.errorString());
        // 提前退出函数,不进行后续操作
        return;
    }
    
    // 设置窗口标题为用户选择的文件名
    setWindowTitle(fileName);
    
    // 创建一个QTextStream对象,用于读取文件内容
    QTextStream in(&file);
    
    // 读取文件的全部内容,并存储到QString对象text中
    QString text = in.readAll();
    
    // 将读取到的文本内容设置到文本编辑器控件中
    ui->textEdit->setText(text);
    
    // 关闭文件,释放资源
    file.close();
}

保存文件

void Notepad::save() {
    QString fileName;

    // 检查当前是否有已保存的文件名(即用户之前是否已保存或打开过文件)
    // 如果没有,我们需要弹出一个保存文件对话框让用户选择保存位置和文件名
    if (currentFile.isEmpty()) {
        fileName = QFileDialog::getSaveFileName(this, "Save"); // 显示保存文件对话框
        currentFile = fileName; // 将用户选择的文件名保存到成员变量currentFile中
    } else {
        // 如果是编辑已存在的文件,则直接使用该文件名
        fileName = currentFile;
    }

    // 使用确定的文件名创建一个QFile对象
    QFile file(fileName);

    // 尝试以只写和文本模式打开文件
    if (!file.open(QIODevice::WriteOnly | QFile::Text)) {
        // 如果文件打开失败(例如,由于权限问题或磁盘空间不足)
        // 显示一个警告消息框,并包含具体的错误信息
        QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
        // 提前退出函数,不进行后续操作
        return;
    }

    // 设置窗口标题为当前保存的文件名
    setWindowTitle(fileName);

    // 创建一个QTextStream对象,用于向文件写入文本
    QTextStream out(&file);

    // 从文本编辑器控件中获取全部文本内容
    QString text = ui->textEdit->toPlainText();

    // 将文本内容写入到文件中
    out << text;

    // 关闭文件,释放相关资源
    file.close();
}

QFile 对象 myfile 与全局变量 currentFile 相关联,currentFile 存储了我们正在处理的文件名。

如果无法打开 myfile,则会显示错误信息,并且该方法会停止执行。

我们创建了一个 QTextStream 对象 out。编辑器缓冲区的内容被转换为纯文本,然后写入到 out 中。

保存为

这与保存文件的程序相似,区别是在这里你需要为将要创建的文件输入一个新的文件名。

void Notepad::saveAs() {
    // 显示一个“另存为”对话框,让用户选择保存的文件名和位置
    QString fileName = QFileDialog::getSaveFileName(this, "Save as");
    
    // 使用用户选择的文件名创建一个QFile对象
    QFile file(fileName);
    
    // 尝试以只写和文本模式打开文件
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        // 如果文件打开失败,显示一个警告消息框,并包含具体的错误信息
        QMessageBox::warning(this, "Warning", "Cannot save file: " + file.errorString());
        // 提前退出函数,不进行后续操作
        return;
    }
    
    // 更新成员变量currentFile为用户选择的新文件名
    currentFile = fileName;
    
    // 更新窗口标题为新保存的文件名
    setWindowTitle(fileName);
    
    // 创建一个QTextStream对象,用于向文件写入文本
    QTextStream out(&file);
    
    // 从文本编辑器控件中获取全部文本内容
    QString text = ui->textEdit->toPlainText();
    
    // 将文本内容写入到文件中
    out << text;
    
    // 关闭文件,释放相关资源
    file.close();
}

打印文件

如果您想使用打印功能,需要在notepad.pro项目文件中添加打印支持:

QT       += printsupport

添加头文件:

#if defined(QT_PRINTSUPPORT_LIB)
#include <QtPrintSupport/qtprintsupportglobal.h>
#if QT_CONFIG(printer)
#if QT_CONFIG(printdialog)
#include <QPrintDialog>
#endif // QT_CONFIG(printdialog)
#include <QPrinter>
#endif // QT_CONFIG(printer)
#endif // QT_PRINTSUPPORT_LIB
void Notepad::on_print_triggered() {
    // 检查是否定义了QT_PRINTSUPPORT_LIB宏,并且是否配置了打印机支持
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
        // 创建一个QPrinter对象,这个对象代表打印机设备
        QPrinter printDev;

        // 检查是否配置了打印对话框
#if QT_CONFIG(printdialog)
            // 创建一个QPrintDialog对象,这个对象允许用户选择打印设置
            QPrintDialog dialog(&printDev, this);
            // 显示打印对话框,如果用户取消操作,则函数返回,不执行打印
            if (dialog.exec() == QDialog::Rejected)
                return;
#endif // QT_CONFIG(printdialog)

        // 使用之前配置好的QPrinter对象,调用textEdit的print方法执行打印操作
        // ui->textEdit是Notepad类成员变量,假设它是一个QTextEdit对象,用于显示和编辑文本
        ui->textEdit->print(&printDev);
#endif // QT_CONFIG(printer)
}

选择字体

首先需要notepad.cpp需要包含以下头文件

#include <QFontDialog>

实现功能:


void Notepad::on_font_triggered() {
    // 定义一个布尔变量fontSelected,用于标记用户是否在字体对话框中选择了字体
    bool fontSelected;
    
    // 调用QFontDialog::getFont静态函数,弹出一个字体选择对话框
    // 该函数返回用户选择的字体,并通过fontSelected参数指示用户是否选择了字体
    // this指针表示字体对话框的父窗口为当前的Notepad对象
    QFont font = QFontDialog::getFont(&fontSelected, this);
    
    // 如果用户选择了字体(即fontSelected为true)
    if (fontSelected) {
        // 将用户选择的字体应用到ui->textEdit上
        // 假设ui->textEdit是Notepad类的一个成员变量,且为QTextEdit对象,用于显示和编辑文本
        ui->textEdit->setFont(font);
    }
    // 如果用户未选择字体,则不执行任何操作(ui->textEdit的字体保持不变)
}

复制、剪切、粘贴、撤消和取消撤回

这些功能只需要调用 ui->textEdit 的相应方法即可实现:

void Notepad::on_copy_triggered()
{
    ui->textEdit->copy();
}

void Notepad::on_cut_triggered()
{
    ui->textEdit->cut();
}


void Notepad::on_paste_triggered()
{
    ui->textEdit->paste();
}

void Notepad::on_undo_triggered()
{
    ui->textEdit->undo();
}

void Notepad::on_redo_triggered()
{
    ui->textEdit->redo();
}

关于和退出

void Notepad::on_about_triggered()
{
    QMessageBox::about(this, tr("关于 Notepad"),
                       tr("这是一个Qt Widget实现的记事本。"));
}

void Notepad::on_exit_triggered()
{
    QCoreApplication::exit();
}

参考:
https://doc.qt.io/qt-5/qtwidgets-tutorials-notepad-example.html
https://www.bilibili.com/video/BV16Y4y1y7iE

相关文章:

  • 2012. 数组美丽值求和【动态规划】
  • 学习threejs,使用LatheGeometry旋转体(榫卯体)几何体
  • texstudio: 编辑器显示行号+给PDF增加行号
  • 大数据实时分析:ClickHouse、Doris、TiDB 对比分析
  • 力扣-数组-34 在排序数组中查找元素的第一个和最后一个位置
  • 代码随想录|二叉树|07二叉树周末总结
  • 使用 Miniforge3 管理 Python 环境的详细指南(基于最新实践和时效性信息,截至 2025 年)
  • ArcGIS Pro 行政区划数据处理:拆分与提取方法详解
  • 修改桌面图标——操作系统程序图标(Windows 10)
  • 2024年广州市智能网联汽车创新实践年度报告
  • 583. 两个字符串的删除操作
  • 【数据库系统概论】第十一章 并发控制
  • dockor
  • 速通C语言——(分支和循环)
  • conda 安装软件报错 Found conflicts! Looking for incompatible packages.
  • 快速使用PPASR V3版不能语音识别框架
  • Docker Compose国内镜像一键部署dify
  • 【前端面试题】Vu3常见的面试题
  • 【网络】poll 与epoll(原理、工作模式LT、ET)
  • Windows 图形显示驱动开发-WDDM 3.2-可调性改进
  • 中科院院士魏辅文已卸任江西农业大学校长
  • 4月深圳新房、二手房成交同比均上涨,“5月有望延续积极向好的发展态势”
  • 韩国法院将李在明所涉案件重审日期延至大选后
  • 创历史同期新高!“五一”假期全国快递揽投超48亿件
  • 出口管制不能将民用技术泛安全化,也不能破坏全球供应链稳定
  • 魔都眼|买买买,老铺黄金新店开业被挤爆:有人排队5小时