前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >二、Qt定时器与文本编辑器制作《QT 入门到实战》

二、Qt定时器与文本编辑器制作《QT 入门到实战》

作者头像
1_bit
发布2022-12-18 17:46:59
9210
发布2022-12-18 17:46:59
举报
文章被收录于专栏:我的知识小屋我的知识小屋

学习目标

  • 了解 qt 的 pixmap
  • 了解 qt 的 label 如何显示图片
  • 了解定时器的开启
  • 了解定时器的关闭
  • 了解文件如何进行读取
  • 了解 QFileDialog 的使用
  • 了解了一个文本编辑器的基本编写
  • 巩固了 connect 的使用

一、制作一个图片浏览器

1.1 Pixmap

在 Qt 中使用 Label 可以显示文本,但 Label 不止可以显示文本,还可以用于图片的显示。

首先我们双击 ui 文件,随后在弹出的设计窗口中创建一个 Label :

在这里插入图片描述
在这里插入图片描述

接着拖动这个 label 的宽高,拖动至一个比较好展示图片的大小:

在这里插入图片描述
在这里插入图片描述

接着我们需要创建一个 QPixmap 对象。

QPixmap 类是一个用于处理图像的类,创建一个 QPixmap 传入对应的路径即可得到这个这个类对于这个图片处理的对象,QPixmap 更适合处理小图片。

如下就是一个创建 QPixmap 类对象的方法:

代码语言:javascript
复制
QPixmap pix("D:\\developer\\QT\\pro\\01\\04\\04\\img\\1.png");

在此传入了一张图片进行对象初始化,接下来就可以直接将这个图片显示在 label 之上。

使用 ui 指定需要显示图片的控件 label,在 label 中有一个 setPixmap 方法,通过 setPixmap 传入 QPixmap 的对象 pix 即可对图片进行设置:

代码如下:

代码语言:javascript
复制
ui->label->setPixmap(pix);

此时代码如下:

在这里插入图片描述
在这里插入图片描述

以上的报错都是 bug,其实代码是正确的,我们此时只需要点击运行,那么即会弹出一个窗口,上面使用了 label 显示一张图片:

在这里插入图片描述
在这里插入图片描述

1.2 定时器

现在已经知道了如何使用 label 显示图片,那么接下来我们制作一个图片的自动切换功能,那么必然是需要定时去执行图片切换,又或者说我们需要一个功能可以去触发图片的切换,并且多张图片的话,切换是重复执行的,那么就需要一个定时重复执行某个操作的功能。

好消息是在 Qt 中自带了定时器,定时器是一个用于对任务执行定时操作的功能,定时器本身存在于 QWidget 基类之中,由于我们在创建对应的项目后,其类是 QWidget 的子类,那么我们在这个类中就可以直接使用定时器。

那么此时我们需要两个按钮,一个用于定时器的开启,另一个按钮用于定时器的关闭,在此创建两个 pushButton 在 Qt 界面之上,并且更改对应的文本:

在这里插入图片描述
在这里插入图片描述

接着我们点击开始按钮触发定时器,那么必然是有一个信号(点击),与一个槽函数,在此右键开始按钮选择转到槽,选择 click 事件:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

转到槽函数后,我们可以使用以下的代码开启定时器:

代码语言:javascript
复制
this->startTimer();

以上代码中的 startTimer就是表示开启一个定时器,startTimer 在此还需要传入一个间隔参数用来设定间隔的时间,这个时间是以毫秒为单位的,若你设置1s 那么则需要写成 1000:

代码语言:javascript
复制
this->startTimer(1000);

那接下来如何完成图片的切换呢?这时我们需要重写一个方法 timerEvent,timerEvent 方法时定时器响应后所执行的函数,其本身存在但需要重写。

此时我们回到 .h 头文件中声明:

代码语言:javascript
复制
virtual void timerEvent(QTimerEvent *event);
在这里插入图片描述
在这里插入图片描述

接着回到 .cpp 文件中对此方法进行重写:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
void MainWindow::timerEvent(QTimerEvent *event){
    
}

在 .cpp 文件中添加以上函数后,我们需要在这个函数中编写切换图片的代码。

此时假如我们有一个文件夹是用于存储需要切换的图片地址,那么我们创建一个 QString 对象进行存储:

代码语言:javascript
复制
QString path("D:\\developer\\QT\\pro\\01\\04\\04\\img\\");

此时我对应的目录下,文件名是如下格式:

在这里插入图片描述
在这里插入图片描述

那么在此我可以创建一个变量,这个变量是一个整形变量,用于代表文件名,但是由于每次都需要在之前的名称基础上往上加1,那么我就不能这个定时器触发函数内进行创建,需要在外部创建这个变量,首先到头文件中进行声明:

代码语言:javascript
复制
int picId;
在这里插入图片描述
在这里插入图片描述

接着再到 cpp 文件中赋初值:

代码语言:javascript
复制
picId=1;
在这里插入图片描述
在这里插入图片描述

那么此时对于一个图片路径的编写就可以由最开始的 path 文件夹路径加上文件名已经文件名后缀即可,那么就可以写成:

代码语言:javascript
复制
path+=QString::number(picId);
path+=".png";

由于 picId 是 number 类型,并不能直接的对字符串进行拼接,在这里使用 QString::number() 方法对其进行类型转化。

现在图片路径有了,那么接下来必然是现实对应的图片,现实图片我们跟之前的方式一样,创建一个 QPixmap 并且指定对应的 ui 对象 label 对其进行显示即可,代码如下:

代码语言:javascript
复制
QPixmap pix(path);
ui->label->setPixmap(pix);

接下来图片的名称进行增加:

代码语言:javascript
复制
picId++;

这样就可以继续下一张图片了,但在此需要注意,咱们的图片只有3张,那么我们需要使图片索引在超过上限时从头开始,那么就需要进行判断:

代码语言:javascript
复制
picId++;
if(4==picId){
   picId=1;
}

此时该函数的所有代码如下:

代码语言:javascript
复制
void MainWindow::timerEvent(QTimerEvent *event){
    QString path("D:\\developer\\QT\\pro\\01\\04\\04\\img\\");
    path+=QString::number(picId);
    path+=".png";
    QPixmap pix(path);
    ui->label->setPixmap(pix);
    picId++;
    if(4==picId){
        picId=1;
    }
}

此时运行项目点击开始后,图片会发生改变:

在这里插入图片描述
在这里插入图片描述

1.3 结束定时

接下来我们还需要使这个定时器结束定时,我们需要使用 killTimer 方法,这个方法本身继承自 QWidget 父类,所以直接使用 this 调用即可,那么代码如下:

代码语言:javascript
复制
this->killTimer();

但此时使用 killTimer 会出现错误,killTimer 需要一个某个定时器的 id 作为参数,指定你 kill 掉这个定时器。那定时器 id 如何拿到呢?其实在 startTimer 时将会返回一个定时器 id ,将这个 id 存储起来即可,由于是不同函数内都需要使用这个 id,那么此时我们需要在头文件中创建一个变量对这个 id 进行存储:

在这里插入图片描述
在这里插入图片描述

接着使用这个变量存储定时器的 id:

在这里插入图片描述
在这里插入图片描述

接着给结束按钮一个槽函数:

在这里插入图片描述
在这里插入图片描述

在这个函数中使用 killTimer 方法传入定时器 id 即可:

代码语言:javascript
复制
void MainWindow::on_pushButton_2_clicked()
{
    this->killTimer(timerId);
}

二、文本编辑器制作

在本章第二点的学习中,我们通过学习文本编辑器制作,从而了解 一般的文件、QFileDialog 以及 巩固自定义事件与槽的知识。

2.1 UI 设计

在正式敲代码之前,我们创建一个项目,设计一下整体的文本编辑器页面。创建好项目后,我们拖动一个 text 的控件拖动到界面之中:

在这里插入图片描述
在这里插入图片描述

在一般的文本编辑器中,一般以文本编辑为主要功能,接下来我们需要使整个文本编辑器占据整个 UI 的空间区域,那如何进行操作呢?若我们直接设置大小使文本编辑控件以及对应的窗口大小相等,那么这个程序的整个窗口都不能够进行拖放,当在某些设备上整体窗口会导致一些困扰;例如程序界面过大、过小等情况,由于不可拖动大小对用户并不友好。此时我们可以点击整个整个窗口,给整个窗口一个垂直布局,给与垂直布局后,这个窗体内的所有空间将会遵从于这个布局,会使整个空间占据整个宽度,那么在运行之后拖动窗体改变窗体大小,由于窗体内的控件遵循垂直布局的规则,那么窗体内的控件将会遵循父窗体的大小而发生改变,这样就很好的解决了窗口过大、过小而不能更改的问题了。

此时点击整个窗体程序:

在这里插入图片描述
在这里插入图片描述

选中整个窗体后,这个窗体将会在周围又蓝色小点代表选中,接下来我们点击对应的垂直布局:

在这里插入图片描述
在这里插入图片描述

点击完毕后整个空间将会占满窗体(这是因为只有一个控件的原因):

在这里插入图片描述
在这里插入图片描述

接着我们给与对应的菜单添加按钮功能。双击菜单(menubar)可更改名称:

在这里插入图片描述
在这里插入图片描述

输入如下截图的内容:

在这里插入图片描述
在这里插入图片描述

按下 enter 键后对应的 &(取地址符)将会消失:

在这里插入图片描述
在这里插入图片描述

这是因为此时在此处输入对应的取地址符加上某一个“按键”,那么则表示对应的快捷键,例如你在程序之中按下 F 那么将会与点击这个 menu 有相同的操作。

接着我们加入打开文件的 menu :

在这里插入图片描述
在这里插入图片描述

再接着添加对应的另存为 menu :

在这里插入图片描述
在这里插入图片描述

还有一个新建文件 menu 忘记添加了,在此添加上:

在这里插入图片描述
在这里插入图片描述

再接着我们更改一下对应的菜单名称,在 ui 设计窗口右上角更改对应的打开和另存为 menu 名称:

在这里插入图片描述
在这里插入图片描述

2.2 新建文件

接下来咱们开始编写新建文件操作的功能。

一般新建文件指的是在在窗体之内新建一个文件文档,此时对于文本编辑框的内容是需要清空的,并且文件名也要做一个提示,此时我们给与这个 new_Action 一个自定义的事件与槽。

因为此时你右键这些 menu 并不能直接转到对应的事件槽,所以此时我们需要对应的 connect 函数进行自定义。

此时我们回到 .h 头文件中,对我们自定义的槽函数进行声明:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
private slots:
    void newActionSlot();

由于此时我们没有给某一个控件一个槽函数,所以此时我们需要自己编写 private 对槽函数的权限进行修饰,并且声明对应的函数。

接着定义完毕后我们需要在 cpp 文件中对其进行实现:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
void MainWindow::newActionSlot(){
}

实现后我们使用 connect 对 new_Action 新建文件操作 ui 绑定对应的槽函数:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
connect(ui->new_Action,&QAction::triggered,this,&MainWindow::newActionSlot);

此时 connect 中 &QAction::triggered 是指 action 的点击事件,并且绑定了一个 newActionSlot 槽函数,有关 QAction 我们可以在 ui 设计框右上角可以看到 new_Action 是属于一个 Action 对象:

在这里插入图片描述
在这里插入图片描述

接着,当点击了新建文件的 action 后,我们需要对应的清空文本编辑框的内容,并且更改当前的 Windows 程序的窗体 title,使其有一个提示,那么槽函数的代码可以写成如下:

代码语言:javascript
复制
void MainWindow::newActionSlot(){
    ui->textEdit->clear();
    this->setWindowTitle("新建文本.txt");
}

以上代码中 setWindowTitle 表示设置当前的窗体程序的标题。我们此时运行程序,在文本编辑框中输入一些内容,随后点击文件选择新建文件,之后将会看见窗体程序的标题发生了改变,并且文本编辑框的内容已被清空:

在这里插入图片描述
在这里插入图片描述

2.3 打开文件

打开文件的前置操作跟新建文件的操作一样,需要在头文件中声明槽函数、在 cpp 文件中实现槽函数 以及使用 connect 方法连接 menu 以及槽函数。

首先在 .h 文件中声明:

在这里插入图片描述
在这里插入图片描述

接着就是在 cpp 文件中实现以及使用 connect 自定义事件与槽:

在这里插入图片描述
在这里插入图片描述

那么接下来我们如何打开文件呢?此时我们需要使用 QFileDialog 类的一个方法打开一个资源选择框,这个方法是 getOpenFileName;首先我们需要在头文件中使用 include 对其引入:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
#include <QFileDialog>

随后在 openActionSlot 槽函数中使用 QFileDialog 调用 getOpenFileName,其中 getOpenFileName 一般接收 4 个参数,第一个是资源选择框的父对象是谁,我们可以指定为 this 表示当前程序;第二个参数是一个提示语;第三个参数为资源选择框打开后的默认路径;第四个参数是打开后显示哪些文件。

那么此时代码写成:

代码语言:javascript
复制
QFileDialog::getOpenFileName(this,"选择一个文本",QCoreApplication::applicationFilePath(),"*.txt");

以上代码中的 QCoreApplication::applicationFilePath() 则是表示取到当前的文件路径,最后一个参数则是表示打开后指定显示 txt 类型文件,此时运行程序后,点击打开将会出现资源选择框:

在这里插入图片描述
在这里插入图片描述

当我们选择某一个文件后,将会弹出对应的文件绝对路径,我们可以使用一个 QString 进行存储,方便接下来读取到所选文件的内容:

代码语言:javascript
复制
QString filename = QFileDialog::getOpenFileName(this,"选择一个文本",QCoreApplication::applicationFilePath(),"*.txt");

若选择文件时并未选中某个文件(取消选择操作、关闭对话框等),其返回值为空,那么在正式读取文件操作之前,我们需要对应的判断当前是否选中文件,此时直接使用 if 判断 filename 的内容是否为 Empty 即可:

代码语言:javascript
复制
if(!filename.isEmpty()){
    
}

此时表示当 filename 不为空时发生操作。接着在 if 判断内,创建一个 file 对象用于接下来对文件的读取,并且在创建时就需要传入 filename:

代码语言:javascript
复制
 QFile file(filename);

接着使用 open 方法对已“装载”路径的 file 对象进行 open,但是由于 open 对象时需要指定你是用什么模式进行读取,可以进行只读、只写等操作,在这里只需要只读,所以使用 QIODevice 方法传入 ReadOnly 作为参数即可:

代码语言:javascript
复制
file.open(QIODevice::ReadOnly);

接着使用 file 对象的 readAll 方法可以一次性读取其文本的内容,并且使用 QByteArray 进行存储;但是要注意,在大文件下不建议这样操作,当前只是作为示例:

代码语言:javascript
复制
QByteArray buf   = file.readAll();

最后直接将这个 buf 转为 string 后设置为 textEdit 的文本内容并且关闭 file 读取即可,此时这个槽函数的所有代码如下:

代码语言:javascript
复制
void MainWindow::openActionSlot(){
    QString filename = QFileDialog::getOpenFileName(this,"选择一个文本",QCoreApplication::applicationFilePath(),"*.txt");
    if(!filename.isEmpty()){
        QFile file(filename);
        file.open(QIODevice::ReadOnly);
        QByteArray buf   = file.readAll();
        ui->textEdit->setText(QString(buf));
        file.close();
    }
}

接着我们运行一下程序,选择一个文本文件后进行打开,内容将会显示在当前的 textedit 之上:

在这里插入图片描述
在这里插入图片描述

2.3 另存为

另存为功能的前置操作跟之前两个功能一致,分别是头文件声明、cpp文件下实现以及connect 链接,在此简述一下步骤。

声明:

代码语言:javascript
复制
void saveActionSlot();

实现:

代码语言:javascript
复制
void MainWindow::saveActionSlot(){

}

链接:

代码语言:javascript
复制
connect(ui->save_Action,&QAction::triggered,this,&MainWindow::saveActionSlot);

前置操作完毕后,我们着重了解如何实现保存功能。

保存功能跟打开文本文件操作类似,都是使用 QFileDialog 进行位置选择,并且最终的保存也是使用 file 对象进行操作,毕竟一个是读一个是写都属于 IO 操作。

既然类型,那么我们在进行保存时的流程都是要打开资源选择框,选择某一个位置进行内容保存,那么铁定是使用 Dialog,在之前是使用 getOpenFileName,是 open操作,那么此时就是 save ,那么就使用 getSaveFileName 方法:

代码语言:javascript
复制
QString filename = QFileDialog::getSaveFileName(this,"选择一个文件",QCoreApplication::applicationFilePath(),"*.txt");

接着同样是判断是否为空:

代码语言:javascript
复制
if(!filename.isEmpty()){

}

接着是使用 file 文件对所选择的位置和保存文件名进行操作,并且此时不是 read 而是 write :

代码语言:javascript
复制
QFile file(filename);
file.open(QIODevice::WriteOnly);

接着使用一个 QString 获取当前的textEdit 的文本:

代码语言:javascript
复制
QString text = ui->textEdit->toPlainText();

创建一个 QByteArray 对象,并且将 textEdit 的文本转为 QByteArray:

代码语言:javascript
复制
QByteArray ba=text.toUtf8();

随后写入文件,并且关闭文件即可,完整代码如下:

代码语言:javascript
复制
void MainWindow::saveActionSlot(){
    QString filename = QFileDialog::getSaveFileName(this,"选择一个文件",QCoreApplication::applicationFilePath(),"*.txt");
    if(!filename.isEmpty()){
        QFile file(filename);
        file.open(QIODevice::WriteOnly);
        QString text = ui->textEdit->toPlainText();
        QByteArray ba=text.toUtf8();
        file.write(ba);
        file.close();
    }
}

此时我们点击保存后将会出现一个资源选择框,我们选择桌面路径,随后点击保存即可对文件进行另存为操作:

在这里插入图片描述
在这里插入图片描述

查看桌面,文件保存成功并且内容已写入:

在这里插入图片描述
在这里插入图片描述

总结

本章节主要介绍了如何使用 qt 创建一个图片浏览器以及一个文本编辑器,并且在其中使用 qt QFileDialog 对文件进行选择已经保存,巩固了 qt 项目创建的基本流程;在此基础上巩固了信号与槽,在制作的过程中使用了垂直布局直接并有效的布局了整个 ui 界面。在此基础上还学习了什么是 menu 以及什么是 menu 的 action,并且在 action 上通过使用取地址符的方式创建了对应的快捷按钮,使其文本编辑器的操作更加的方便,这一节还学习了对应的定时器,了解了通过定时器可以对应的创建定时任务,例如制作一个壁纸切换的桌面、定时执行一些重复操作等。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 学习目标
  • 一、制作一个图片浏览器
    • 1.1 Pixmap
      • 1.2 定时器
        • 1.3 结束定时
        • 二、文本编辑器制作
          • 2.1 UI 设计
            • 2.2 新建文件
              • 2.3 打开文件
                • 2.3 另存为
                • 总结
                相关产品与服务
                图片处理
                图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档