IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++学习27qt(三)Qt自定义控件封装,事件处理,绘画和文件读写 -> 正文阅读

[C++知识库]c++学习27qt(三)Qt自定义控件封装,事件处理,绘画和文件读写

Qt自定义控件封装

步骤

  1. 添加类 Qt-设计师界面类 .h .cpp .ui
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    此时就添加成功
  2. 选择一个QWidget控件,添加到主界面,右击选择提升为
    . 在这里插入图片描述
    此时,我们要将1步骤的Qt界面设计类添加进去,选择提升
    如果

在这里插入图片描述
则说明替换成功

  1. 设置自定义控件封装内组件之间的联动效果,在.cpp文件中设置
smallWiget::smallWiget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::smallWiget)
{
    ui->setupUi(this);
    //QSpinBox移动 QSlider跟着移动
    void(QSpinBox:: *spinSignal)(int) = &QSpinBox::valueChanged;
    connect(ui->spinBox,spinSignal,ui->horizontalSlider,&QSlider::setValue);

    //QSlider移动 QSpinBox 跟着改变

    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
  1. 设置一些接口,供外部去使用 :(在.h文件中声明,在.cpp文件中实现)
//smallWiget.h文件中
class smallWiget : public QWidget
{
    Q_OBJECT

public:
    explicit smallWiget(QWidget *parent = 0);
    //定义的方法:
    void setData(int val);
    int getData();
    //end
    ~smallWiget();

private:
    Ui::smallWiget *ui;
};
//smallWiget.cpp文件
void smallWiget::setData(int val){
    ui->spinBox->setValue(val);
}

int smallWiget::getData(){
    return ui->spinBox->value();
}
  1. 外部的简单使用
 //获取按钮
    connect(ui->btn_getValue,&QPushButton::clicked,[=](){
        qDebug()<<"当前的数值为:"<< ui->widget->getData();
    });
    //设置一半按钮
    connect(ui->btn_setHalf,&QPushButton::clicked,[=](){
        ui->widget->setData(50);
    });
  1. 效果展示
    请添加图片描述

Qt中的事件处理

捕获QLabel中的鼠标事件

如果我们想捕获QLabel的鼠标事件,而控件本身的事件无法满足需求,就需要我们重写其方法来满足需求
这样我们就需要创建一个类去继承QLabel,再在界面中添加一个空的容器,使其提升,再在其头文件中声明需要的方法,在.cpp文件中对具体需求做实现

鼠标的一些事件:

  • 鼠标进入enterEvent
  • 鼠标离开leaveEvent
  • 鼠标按下mousePressEvent
  • 鼠标释放mouseReleaseEvent
  • 鼠标移动mouseMoveEvent
  • 设置鼠标追踪 this->setMouseTracking(true); 默认是true

定时器

定时器事件

 void timerEvent(QTimerEvent *e);

可以通过e获取定时器的id

e->timerId();

通过定时器的id,我们可以在开启不同的定时器,做出不同的实现
如:

void Widget::timerEvent(QTimerEvent *e){
    //使用QTimerEvent的timeId()方法拿到具体的开启定时器的值
    if(e->timerId()==id1){
        static int num =1;
        //加上static 使其就初始化一次,如果不加static那么num会在timerEvent()方法运行时一直走,导致显示的一直是1
        ui->label->setText(QString::number(num++));
    }else{
        static int num2 =10;
        ui->label_2->setText(QString::number(num2+=10));
    }
}

当我们有多个定时器时,我们可以使用定时器的类QTimer去创建定时器,使代码更便于管理
如:

//利用定时器的类QTimer实现定时功能
    QTimer * timer = new QTimer(this);
    //启动定时器
    timer->start(500);
    connect(timer,&QTimer::timeout,[=](){
       //定时功能
        static int num3 = 9;
        ui->label_3->setText(QString::number(num3+=9));
    });
//关闭定时器(这里没有用槽和信号,尽量用事件或方法去包裹使用,再不济加个判断
timer->stop();

注意:两个实现定时器的方法没有优劣之分,按照需求选择合适的就可

事件分发器

  1. bool event(QEvent *e)
  2. e->type()所有Qt中的事件
  3. 事件分发器可以做事件的拦截操作,如果用户进行了拦截,在对应事件里返回true代表自己处理事件

事件过滤器

使用事件过滤器可以做更高级拦截

使用事件过滤器有两步:

  1. 给对应的控件安装事件过滤器
ui->label->installEventFilter(this);
  1. 重写eventFilter
//.h
bool eventFilter(QObject *watched, QEvent *event);

//.cpp
bool Widget::eventFilter(QObject *watched, QEvent *event){
    //参数1 对比控件  参数2对比事件
    //对比控件
    if(obj==ui->label){
        //对比事件
        if(event->type()==QEvent::MouseButtonPress){
            //处理方式
        return true;   //如果返回true 代表用户自己处理 
        }
    }    
    return QWidget::eventFilter(obj,event);//默认处理    
}

绘画

基本绘画

  1. 绘画方法
//绘画事件
    void paintEvent(QPaintEvent *event);
  1. 声明画家
 //声明一个画家的对象 在窗口设备中绘制图片
    QPainter painter(this);
  1. 设置画笔
//指定画笔
    QPen pen(QColor(255,0,0));
    //设置笔宽
    pen.setWidth(3);
    //设置笔风格
    pen.setStyle(Qt::DotLine);
    //给画家拿个笔
    painter.setPen(pen);
  1. 设置画刷
//画刷 用来填充画家画出的封闭图形
    QBrush brush(Qt::cyan);
    //设置画刷风格
    brush.setStyle(Qt::Dense6Pattern);
    //给画家设置画刷
    painter.setBrush(brush);
  1. 绘制一些基础图形
 //画线
    painter.drawLine(QPoint(0,0),QPoint(100,100));
    //画圆(椭圆)当rx=ry时,画出的就是一个圆
    painter.drawEllipse(QPoint(100,100),50,50);
    //画矩形 QRect()四参数说明,前面两个代表坐标,后面两个代表宽高
    painter.drawRect(QRect(20,20,50,50));
    //画文字 前面的参数代表一个矩形范围,后面的参数是目标文字
    painter.drawText(QRect(10,200,120,100),"好好学习,天天向上");
  1. 效果展示
    在这里插入图片描述

高级绘画设置

1.设置抗锯齿

   painter.drawEllipse(QPoint(100,100),50,50);
//   //设置抗锯齿 效率更低,但图片更清晰
  painter.setRenderHint(QPainter::Antialiasing);
  painter.drawEllipse(QPoint(250,100),50,50);

在这里插入图片描述
2.移动画家的位置

 painter.drawRect(QRect(20,20,50,50));
   //移动画家的位置,画家初始位置为(0,0) 下面将(100,0)当作(0,0)去使用
   painter.translate(QPoint(100,0));
   painter.save();//保存画家的位置
   painter.drawRect(QRect(20,20,50,50));
   //移动画家的位置,画家初始位置为(0,0) 下面将(100,0)当作(0,0)去使用
   painter.translate(QPoint(100,0));
   //将画家的位置还原到上一次
   painter.restore();
   painter.drawRect(QRect(20,20,50,50));

在这里插入图片描述
3. 利用画家绘制资源图片

#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    posX =10;
    //点击按钮实现图片移动
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        //手动调用paintEvent函数,利用update
        posX+=20;
        update();
    });
}
void Widget::paintEvent(QPaintEvent *event){
   QPainter painter(this);
   //如果超过屏幕的范围,将posX设置回来
   if(posX>this->width()){
       posX =10;
   }
   //利用画家绘制图片
   painter.drawPixmap(posX,100,QPixmap(":/image/page.png"));
}

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

效果图
请添加图片描述

绘图设备

绘图设备有一下几种:

QPixmap , QBitmap , QImage , QPicture , QWidget

QPixmap

QPixmap做绘图设备
在不同平台做了显示的优化

QPixmap简单使用案例

//QPixmap做绘图设备
    //在不同平台做了显示的优化
    QPixmap pix(300,300);
    pix.fill(Qt::white); //设置QPixmap的填充色,默认是黑色
    QPainter painter(&pix);
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse(QPoint(150,150),100,100);
    //保存
    pix.save("E:\\pix.png");

在这里插入图片描述

QImage

QImage做绘图设备
可以对像素进行访问

 QImage img(300,300,QImage::Format_RGB32);
    img.fill(Qt::white);
    QPainter painter(&img);
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(150,150),100,100);
    img.save("E:\\img.png");

QPicture

QPicture做绘图设备
记录和重现QPainter的各条命令
这个就比较有意思了,我们可以设置生成文件的格式,并且如果不是常规默认的后缀名,那么就只有我们的Qt程序可以去打开它了

#include "widget.h"
#include "ui_widget.h"
#include<QPainter>
#include<QPicture>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
   //QPicture做绘图设备
    //记录和重现QPainter的各条命令
    QPicture pic;
    QPainter painter;
    painter.begin(&pic);//开始执行命令,且绑定绘图设备
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse(QPoint(150,150),100,100);
    painter.end();//结束执行命令
    pic.save("E:\\pic.wjl");//保存
    //这个格式后缀可以随便写,只要不是常规默认,是没办法直接打开预览的
}

void Widget::paintEvent(QPaintEvent *event){
    //重现QPicture 的绘图命令
    QPainter painter(this);
    QPicture pic;
    pic.load("E:\\pic.wjl");
    painter.drawPicture(0,0,pic);

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

在这里插入图片描述
QBitmap 色深限定为1 ,只有黑白色

QFile 文件读写

规律

和c++的方式一样,只是更换了类,还是需要路径作为文件的参数,且需要指定的打开方式,且其有默认的编码格式为utf-8

案例

#include "widget.h"
#include "ui_widget.h"
#include<QFileDialog>
#include<QMessageBox>
#include<QTextCodec>
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 实现效果: 点击按钮 选择文件
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        //拿到文件路径
      QString filePath =  QFileDialog::getOpenFileName(this,"选择文件","E:\\weixintool\\微信web开发者工具") ;
      //将文件路径设置到lineEdit中
      if(filePath.isEmpty()){
          QMessageBox::warning(this,"打开失败","文件路径为空");
          return;
      }
      ui->lineEdit->setText(filePath);

      //设置编码格式
      QTextCodec *code = QTextCodec::codecForName("gbk");//默认的编码格式是utf-8
      //将文件中的内容放入到textEdit中
      QFile file(filePath);//设置目标文件
      //设置打开方式
      file.open(QIODevice::ReadOnly);//以只读的方式打开
      QByteArray arr;
      //读取全部的方式:
      //arr = file.readAll();

      //按行读取
      while(!file.atEnd()){
          arr += file.readLine();
      }
      //显示arr数据
      ui->textEdit->setText(arr);
      //使用设置好的编码格式
//      ui->textEdit->setText(code->toUnicode(arr));

      //用完后要关闭文件对象
      file.close();

      //写文件
      file.open(QIODevice::Append);//利用追加的方式写入
      file.write("这是添加的条目");
      file.close();
    });
}

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

请添加图片描述

QFileInfo类

直接使用:

//文件信息类
      QFileInfo info(filePath);
      qDebug()<<"大小"<<info.size()<<"后缀名:"<<info.suffix()<<"文件名:"<<info.fileName()<<"文件的完整路径:"
             <<info.absoluteFilePath();
      qDebug()<<"创建日期"<<info.created().toString("yyyy/MM/dd hh:mm:ss");
      qDebug()<<"最后修改的日期"<<info.lastModified().toString("yyyy-MM-dd hh:mm:ss");

如果使用与日期有关的,需要导入QDate类
利用文件的后缀名,可以做过滤文件的作用(这里不展示)
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 20:56:54  更:2022-10-22 20:59:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 3:40:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码