Qt 入门学习路线

本文深入介绍了Qt框架,包括其跨平台性、信号槽机制、对象树和在线帮助系统。通过一个电子表格应用的实战案例,展示了如何使用Qt进行GUI编程,涉及文件操作、表格交互、搜索及跳转功能。此外,文章还提供了详细的代码分析,涵盖了文件读写、菜单创建、单元格操作等关键功能。

知识点


设计模式

  • 创建型模式
  • 结构型模式
  • 行为模式

C++

  • 指针和引用

STL

  • 容器
  • 迭代器
  • 算法
  • 仿函数
  • 适配器
  • 空间配置器

智能指针

  • unique_ptr
  • shared_ptr

Qt

  • 元对象系统

    • QObject基类
    • Q_OBJECT()宏
    • moc元对象编译器
  • 信号与槽机制

    • 原理:signals/slots - staticMetaObject - connect - 存放至map - emit触发 - active函数
    • 优点:
    • 缺点:
  • QThread

  • QTcpServer

  • QTcpSocket


一、Qt框架概述


1. 什么是Qt?

Qt是一个用C++编写的、成熟的、跨平台的GUI工具包,它是挪威Trolltech公司的产品,该公司为商业市场开发、销售和支持Qt及其相关软件。

Qt作为一个出色的软件框架,除了为应用程序提供GUI库,还提供了容器、输入输出、数据库、多线程、网络、三维图形等开发工具,十分强大。

Qt除了价格高昂的商用版本,还对自由软件社区提供了免费开源版本。

2. Qt的优点

  • 跨平台
    Qt的第一大优点,也是最令人印象深刻的特点就是它的跨平台性。
    Qt支持Linux、类UNIX系统、Windows、Mac OS、甚至嵌入式平台。
    Qt对于每一种操作系统平台,都提供了对应的底层类库,也就是在OS层和应用层之间增加了一个“平台适应层”,而对应用程序提供出来的接口时一致的。所以同样一套代码,不管放在Linux还是Windows,几乎不用改动就可以通过编译,此特性大大方便了软件的移植。

  • 信号槽机制
    信号与信号处理时GUI应用程序用来相应用户输入的主要机制,也是一个GUI库的核心特征。
    Qt的信号处理机制由 信号 构成。使用信号槽功能的类需要在类声明中添加 Q_OBJECT 宏声明,然后使用 QObject::connect() 函数进行连接,它明确地将信号和信号处理函数联系了起来。
    在这里插入图片描述

  • Qt对象树
    Qt对象之间是可以存在父子关系的。父对象会保存一个子对象链表,记录所有指向其子对象的指针,同时子对象也会保留指向父对象的指针。当一个父对象被析构时,其子对象也会被析构。
    所以销毁一个对象,它的所有子孙后代对象都会被销毁,表现在Qt对象树上就是删除一个节点,那这个节点下的整个分支都会被删除。这种特性让开发人员在一个对象下new出若干子对象后,不需要手动去delete,只需要销毁一个父对象,它们都会被自动销毁,大大减轻开发人员的负担。

    使用此特性时仍需注意的问题: 对象树和析构函数冲突

  • 在线帮助系统
    由于Qt提供的封住类和接口十分丰富,Qt Creator 在文本编辑器中提供了在线帮助系统,只需要选中要查询的内容,按下F1,即可弹出相应的帮助页面,极大地减少了查询和学习的时间。
    在这里插入图片描述


二、Qt体系


1. Qt模块图

在这里插入图片描述

2. Qt继承树

在这里插入图片描述

3. Qt学习路线图

在这里插入图片描述

三、Qt编程练习


Spreadsheet 制作一个电子表格

项目总览

  • 项目介绍
    该项目会创建一个电子表格,功能类似Excel表格。
    有基本的单元格编辑,复制,剪切,删除等功能。
    有批量复制,搜索,排序等进阶功能。
    有保存文件,打开文件,展示最近文件的功能。

  • 所有文件
    总文件个数17,总代码量约1800行
    在这里插入图片描述

  • 主窗口类 (继承于QMainWindow类)
    mainwindow.h
    mainwindow.cpp
    主窗口类负责管理整体的布局,生成顶部工具栏以及快捷按钮,并且包含了提供核心功能的电子表格。主窗口还负责文件的保存与读取,以及提供第二级功能弹窗。
    在这里插入图片描述

  • 表格类 (继承于QTableWidget类)
    spreadsheet.h
    spreadsheet.cpp
    表格类只生成由单元格组成的空白表格,有CCell单元格类作为私有成员。表格类的主要意义是接收输入(键盘、鼠标)并显示内容,以及提供所有跟表格内容有关的操作,比如拷贝、粘贴和剪切单元格,完成公式的计算,打开文件后的表格显示,从表格中读取数据,搜索数据等等…
    在这里插入图片描述

  • 单元格类 (继承于QTableWidgetItem,能很好地与表格类配合)
    cell.h
    cell.cpp
    单元格类是最小的单元,所有数据最终都要通过它来显示和返回,它主要提供公式设置和解析的功能。
    在这里插入图片描述

  • 搜索对话框类 (继承于QDialog类)
    sortdialog.h
    sortdialog.cpp
    在主窗口的Edit菜单点击Find搜索选项,或者按下快捷栏的Find按钮,都会弹出搜索弹窗。该窗口除了提供基本的搜索功能外,还增加了两个细微的操作来增加搜索的精确性:反向搜索和大小写感。搜索时勾选该选项(CheckBox)即可。只有当输入框中内容满足一定条件,Find按钮才会被激活,这里用到了Qt提供的正则表达式。
    在这里插入图片描述

  • 跳转对话框类 (继承于QDialog类)
    gotocelldialog.ui
    ui_gotocelldialog.h
    gotocelldialog.cpp
    该对话框的作用很简单,跳转到用户指定的单元格(比如A21、H55)。
    (创建此对话框时用到了Qt Designer,因此生成了对应的ui文件)
    在这里插入图片描述
    在这里插入图片描述

  • 排序对话框类 (继承于QDialog类)
    sortdialog.ui
    ui_sortdialog.h
    sortdialog.cpp
    该对话框提供对选中区域的排序功能,所有被选中的列号都会被加载进Column选项,你可以任选一列进行排序,按下more按钮,允许你再选择两列进行排序,这里对more键的toggle信号和后两个设置框的visible属性作了信号槽连接。
    (创建此对话框时用到了Qt Designer,因此生成了对应的ui文件)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

关键代码分析

  • 主窗口功能 - 另存为SaveAs
    以下是SaveAs操作会调用到的三个函数
    在主函数中,SaveAs作为槽函数,在SaveAsAction被触发后调用。此函数调用 QFileDialog类 提供的 getSaveFileName 函数,会弹出一个已封装好的文件保存对话框,可以在参数列表中设置标题、保存类型。
    保存后会返回文件名filename,为了之后交给spreasheet以保存当前数据内容。所以在return处调用saveFile私有函数
bool MainWindow::saveAs()
{
   
   
    QString filename = QFileDialog::
    					getSaveFileName(
    						this,
                        	tr("Save Spreadsheet"),
                            tr("Spreadsheet files (*.sp)"));
    if (filename.isEmpty()) {
   
   
        return false;
    }
    return saveFile(filename);
}

saveFile函数把filename交给spreadsheet,让其把表格中的数据写入,若写入成功,则设置为当前文件并给出提示。

bool MainWindow::saveFile(const QString& filename)
{
   
   
    if (!spreadSheet->writeFile(filename)) {
   
   
        statusBar()->showMessage(tr("Saving canceled"), 2000);
        return false;
    }

    setCurrentFile(filename);
    statusBar()->showMessage(tr("File saved"), 2000);
    return true;
}

在CSpreadSheet类中完成数据写入操作。先用文件名构造一个 QFile 对象,然后调用open打开,若文件打开成功,则以此创建一个 QDataStream 数据流对象。最开始写入的MAGIC_NUMBER用于标识.sp文件,在读取数据的时候需要通过判断文件头来确定是否是sp文件。接着,通过遍历表格,将有公式的行号、列号和公式写入数据流。在此期间,将鼠标设为等待状态图形。

bool CSpreadSheet::writeFile(const QString& filename)
{
   
   
    QFile file(filename);
    if (!file.open(QIODevice::WriteOnly)) {
   
   
        QMessageBox::warning(this, tr("Spreadsheet"),
                             tr("cannot write file %1:\n%2.")
                             .arg(file.fileName())
                             .arg(file.errorString()));
        return false;
    }

    QDataStream out(&file);
    out.setVersion(QDataStream::Qt_5_12);
    out << quint32(MAGIC_NUMBER);

    QApplication::setOverrideCursor(Qt::WaitCursor);
    for (int row = 0; row < rowCount(); ++row) {
   
   
        for (int col = 0; col < columnCount(); ++col) {
   
   
            QString str = formula(row, col);
            if (!str.isEmpty()<
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值