【Qt】day3 自定义控件、框架、定时器、QPainter、QFile

文章目录

  • 自定义控件封装
  • 自定义框架
  • 定时器
    • 第一种方式
    • 第二种方式 (推荐)
  • 事件分发器
  • QPainter
    • 基本操作
    • 高级设置
      • 抗锯齿
      • 移动坐标原点
    • 画家画资源图片,并实现手动移动
  • 作业
  • QPaintDevice绘图设备
    • QPixmap
    • Qimage
    • QPicture
  • QFile文件读写操作
    • QFileInfo文件信息获取

自定义控件封装

1.创建新文件-Qt-设计师界面类(.h .cpp .ui)
在这里插入图片描述

2.以QSpinBox和QSlider为例子。在.ui中设计这两个控件
在这里插入图片描述

3.在主ui中添加Widget,并把它升级。
在这里插入图片描述
在这里插入图片描述

类名称为自己在添加新文件(设计师界面类)写的。

若这个自定义控件经常用到,可以设为全局包含

  1. 添加两个按钮btn_get和btn_set
    在这里插入图片描述

5.实现函数:改变数字,滑动条跟着移动 ,信号槽监听。在新组建.cpp中完成实现。

    //QSpinBox移动 QSlider跟着移动void(QSpinBox:: * spSignal)(int) = &QSpinBox::valueChanged;connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);//QSlider滑动 QSpiBox数字跟着改变connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);

6.提供 getNum 和 setNum对外接口:在新组件.h声明两个函数。在新组件.cpp中实现这两个函数
在这里插入图片描述
6.

自定义框架

1.创建新文件-C/C+±Class,我这里命名为myLable.
在这里插入图片描述
在这里插入图片描述
2.改3处类名
在这里插入图片描述
在这里插入图片描述

3.在头文件写函数声明

    //鼠标进入事件void enterEvent(QEnterEvent *event);//鼠标离开事件void leaveEvent(QEvent *);//鼠标按下virtual void mousePressEvent(QMouseEvent *ev);//鼠标释放virtual void mouseReleaseEvent(QMouseEvent *ev);//鼠标移动virtual void mouseMoveEvent(QMouseEvent *ev);

在这里插入图片描述
4.在源文件实现函数

myLabel::myLabel(QWidget *parent): QLabel{parent}
{//设置鼠标追踪状态setMouseTracking(true);
}// 鼠标进入事件
void myLabel::enterEvent(QEnterEvent *event)
{qDebug()<<"鼠标进入了";}void myLabel::leaveEvent(QEvent *)
{qDebug()<<"鼠标离开了";
}//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{// if(ev->button()==Qt::LeftButton){QString str = QString("鼠标按下了 x=%1 y=%2 globalX= %3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;// }}
//鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{// if(ev->button()==Qt::LeftButton){QString str = QString("鼠标按下了 x=%1 y=%2 globalX= %3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;// }
}//鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
//    if(ev->buttons() & Qt::LeftButton){*/ //移动是一个状态QString str = QString("鼠标移动了 x=%1 y=%2 globalX= %3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;// }
}
鼠标事件代码
鼠标进入enterEvent
鼠标离开leaveEvent
鼠标按下mousePressEvent ( QMouseEvent ev)
鼠标释放mouseReleaseEvent
鼠标移动mouseMoveEvent
鼠标坐标ev->x() x坐标 ev->y() y坐标
判断所有按键ev->button()
左按键/右按键Qt::LeftButton / Qt::RightButton
判断组合按键 判断move时候的左右键 结合 &ev->buttons()
格式化字符串QString( “ %1 %2 ” ).arg( 111 ).arg(222)
设置鼠标追踪setMouseTracking(true);

定时器

第一种方式

1.在ui界面创建两个label_2和label_3
在这里插入图片描述
2.在widget.h中,写定时器的函数声明和2个公有变量

public:Widget(QWidget *parent = nullptr);~Widget();//重写定时器事件void timerEvent(QTimerEvent *);int id1;//定时器1的唯一标识int id2;//定时器2的唯一标识private:Ui::Widget *ui;
};

3.在源文件写函数实现和调用定时器。

Widget::Widget(QWidget *parent): QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//启动定时器id1 = startTimer(1000);id2 = startTimer(2000);
}void Widget::timerEvent(QTimerEvent *ev)
{if(ev->timerId() == id1){ static int num = 1;//label2 每隔1秒+1ui->label_2->setText(QString::number(num++));}if(ev->timerId() == id2){static int num2 = 1;//label3 每隔2秒+1ui->label_3->setText(QString::number(num2++));}
}

在这里插入图片描述

第二种方式 (推荐)

1.ui界面设计两个按钮btn,btn1,一个label_4
在这里插入图片描述

2.在源文件,实现按键的功能和启动定时器

加入头文件<QTimer>

在这里插入图片描述

利用定时器类 QTimer
创建定时器对象 QTimer * timer = new QTimer(this);
启动定时器 timer->start(毫秒)
每隔一定毫秒,发送信号 timeout ,进行监听
暂停 timer->stop

事件分发器

相当于总控,在一些情况下可以屏蔽某些键位

在这里插入图片描述

以屏蔽“鼠标按下”为例.
1.在头文件添加函数声明

    //通过event事件分发器 拦截 鼠标按下事件bool event(QEvent *e);

在这里插入图片描述

2.在源文件实现函数

bool myLabel::event(QEvent *e)
{if(e->type()==QEvent::MouseButtonPress){QMouseEvent * ev = static_cast<QMouseEvent *>(e); //转为QMouseEvent类型QString str = QString("Event函数中::鼠标按下了 x=%1 y=%2 globalX= %3 globalY = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug()<<str;return true;  //ture代表用户自己处理这个事件,不向下分发}//其他事件 交给父类处理 默认处理return QLabel::event(e);
}

3.效果如图
在这里插入图片描述

小结:
用途:事件的分发,也可以做拦截操作
bool event( QEvent * e);
如果返回值是true 代表用户处理这个事件,不向下分发了

QPainter

基本操作

1.在头文件声明函数

    //绘图事件void paintEvent(QPaintEvent * );

在这里插入图片描述
2.在源文件实现函数

记得要引入类#include <QPainter>

void Widget::paintEvent(QPaintEvent * )
{//实例化画家对象 this指定的是绘画设备QPainter painter(this);//设置画笔QPen pen(QColor(255,0,0));//设置画笔宽度pen.setWidth(3);//设置画笔风格pen.setStyle(Qt::DotLine);//让画家使用这支笔painter.setPen(pen);//设置画刷QBrush brush(Qt::cyan);//设置画刷风格painter.setBrush(Qt::Dense7Pattern);//让画家使用画刷painter.setBrush(brush);//画线painter.drawLine(QPoint(0,0),QPoint(100,100));//画圆painter.drawEllipse(QPoint(100,100),50,50);//画矩形painter.drawRect(QRect(20,20,60,60));//画文字painter.drawText(QRect(10,200,150,50),"好好学习,天天向上");
}

小结:
绘图事件 void paintEvent()
声明一个画家对象 QPainter painter(this) this指定绘图设备
画线、画圆、画矩形、画文字
设置画笔 QPen 设置画笔宽度 、风格
设置画刷 QBrush 设置画刷 风格

高级设置

抗锯齿

1.在头文件声明函数

    //绘图事件void paintEvent(QPaintEvent * );

2.在源文件函数实现

void Widget::paintEvent(QPaintEvent * )
{QPainter painter(this);painter.drawEllipse(QPoint(100,50),50,50);//设置 抗锯齿能力 效率较低painter.setRenderHint(QPainter::Antialiasing);painter.drawEllipse(QPoint(200,50),50,50);
}

移动坐标原点

void Widget::paintEvent(QPaintEvent * )
{//画矩形painter.drawRect(QRect(20,20,50,50));//移动画家painter.translate(100,0);//保存画家状态painter.drawRect(QRect(20,20,50,50));painter.translate(100,0);//还原画家保存状态painter.drawRect(QRect(20,20,50,50));
}

画家画资源图片,并实现手动移动

1.导入资源图片
在这里插入图片描述
2.在ui界面设计一个按钮
在这里插入图片描述

3.在头文件声明函数和全局变量

public:Widget(QWidget *parent = nullptr);~Widget();//绘图事件void paintEvent(QPaintEvent * );int posX=0;

4.在源文件实现函数

#include <QPainter>//画家void Widget::paintEvent(QPaintEvent * )
{QPainter painter(this);//如果超出屏幕 从0开始if(posX>this->width()){posX=0;}painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));
}

5.在源文件实现按钮

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//点击移动按钮 移动图片connect(ui->pushButton,&QPushButton::clicked,[=](){posX+=20;//如果要手动调用绘图事件 用update更新update();});
}

6.实现效果如下
在这里插入图片描述

小结:
抗锯齿 效率低
painter.setRenderHint(QPainter::Antialiasing);
对画家进行移动
painter.translate(100,0);
保存状态 save
还原状态 restore
如果想手动调用绘图事件 利用update
利用画家画图片 painter.drawPixmap( x,y,QPixmap( 路飞) )

作业

实现路飞的自动移动,即自动连播。

头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void paintEvent(QPaintEvent * );int posX=0;private:Ui::Widget *ui;
};
#endif // WIDGET_H

源文件

#include "widget.h"
#include "ui_widget.h"
#include <QPainter>//画家
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QTimer * timer = new QTimer(this);timer->start(500);connect(timer,&QTimer::timeout,[=](){posX+=20;update();});
}void Widget::paintEvent(QPaintEvent * )
{QPainter painter(this);if(posX>this->width()){posX=0;}painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));
}Widget::~Widget()
{delete ui;
}

QPaintDevice绘图设备

QPixmap

对不同平台做了显示的优化
QPixmap pix( 300,300)
pix.fill( 填充颜色 )
利用画家 往pix上画画 QPainter painter( & pix)
保存 pix.save( “路径”)

Qimage

可以对像素进行访问
使用和QPixmap差不多 QImage img(300,300,QImage::Format_RGB32);
其他流程和QPixmap一样
可以对像素进行修改 img.setPixel(i,j,value);

QPicture

记录和重现 绘图指令
QPicture pic
painter.begin(&pic);
保存 pic.save( 任意后缀名 )
重现 利用画家可以重现painter.drawPicture(0,0,pic);

QFile文件读写操作

1.在ui文件创建如下页面
在这里插入图片描述

2.文件为utf-8文件,进行读操作

添加头文件#include <QFileDialog> #include <QFile>

    //点击选取文件按钮,弹出文件对话框connect(ui->pushButton,&QPushButton::clicked,[=](){QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\Gemini\\Desktop\\Qt-学习\\QT资料\\day3资料\\Doc");//将路径放入到lineEdit中ui->lineEdit->setText(path);//读取内容 放入到 textEdit中QFile file(path);  //参数是读取文件的路径//设置打开方式file.open(QIODevice::ReadOnly);//QByteArray array = file.readAll();两种读结果都一样QByteArray array;while(!file.atEnd()){array+=file.readLine();//按行读   }//将读取到的数据放入textEdit中ui->textEdit->setText(array);//对文件对象进行关闭file.close();});

3.进行写操作

    connect(ui->pushButton,&QPushButton::clicked,[=](){QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\Gemini\\Desktop\\Qt-学习\\QT资料\\day3资料\\Doc");//将路径放入到lineEdit中ui->lineEdit->setText(path);//读取内容 放入到 textEdit中QFile file(path);  //参数是读取文件的路径//进行写操作file.open(QIODevice::Append);//用追加方式去进行写file.write("啊啊啊啊");file.close();
}

4.读写结合如下
在这里插入图片描述

QFileInfo文件信息获取

添加头文件include <QFileInfo>

在源代码

    connect(ui->pushButton,&QPushButton::clicked,[=](){QString path = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users\\Gemini\\Desktop\\Qt-学习\\QT资料\\day3资料\\Doc");//将路径放入到lineEdit中ui->lineEdit->setText(path);QFileInfo info(path);qDebug()<<"大小:"<<info.size()<<"后缀名"<<info.suffix()<<"文件名称:"<<info.fileName()<<"文件路径:"<<info.filePath();qDebug()<<"创建日期:"<<info.birthTime().toString("yyyy/MM/dd hh:mm:ss");qDebug()<<"最后修改日期"<<info.lastModified().toString("yyyy/MM/dd hh:mm:ss");}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/867669.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移动校园(3):处理全校课程数据excel文档,实现空闲教室查询与课程表查询

首先打开教学平台 然后导出为excel文档 import mathimport pandas as pd import pymssql serverName 127.0.0.1 userName sa passWord 123456 databaseuniSchool conn pymssql.connect(serverserverName,useruserName,passwordpassWord,databasedatabase) cursor conn.cur…

昇思11天

基于 MindSpore 实现 BERT 对话情绪识别 BERT模型概述 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由Google于2018年开发并发布的一种新型语言模型。BERT在许多自然语言处理&#xff08;NLP&#xff09;任务中发挥着重要作用&am…

【C++】map和set详解

目录 1. 关联式容器 2. 键值对pair 3. 树形结构的关联式容器 4. set 4.1 set的介绍 4.2 set的构造 4.3 set的迭代器 4.4 set的容量 4.5 set的常用函数 5. multiset 6. map 6.1 map的介绍 6.2 map的构造 6.3 map的迭代器 6.4 map的容量 6.5 map的operator[] 6.6…

【虚幻引擎】UE4初学者系列教程开发进阶实战篇——生存游戏案例

一、课程体系 1 学前必读 2 Character类相关基础 -人物移动控制 -动画蓝图 3 常见游戏机制基础 -碰撞器、触发器 -物体使用接口 -视角切换 4其他相关设计 -背包系统 -锻造系统 -物体破碎效果 -简易种植系统 -互动物体动画 5课程结语 二、UI部分 思维导图部分 实操部分 …

如何借助AI在20分钟内写一个springboot单表的增删改查

目录 1. AI工具介绍2. 写代码的正确顺序2.1 编写 Entity 类&#xff1a;2.2 编写 Mapper 接口&#xff1a;2.3 编写 Mapper XML 文件&#xff08;如果使用 MyBatis&#xff09;&#xff1a;2.4 编写 Service 接口&#xff1a;2.5 编写 Service 实现类&#xff08;ServiceImpl&a…

【pyhton学习】深度理解类和对象

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一、一切皆对象1.1 对象的概念1.2 如何创建类对象1.3 类型检测 二、属性与方法2.1 如何查看属性与方法2.2 属性和方法…

C语言 | Leetcode C语言题解之第220题存在重复元素III

题目&#xff1a; 题解&#xff1a; struct HashTable {int key;int val;UT_hash_handle hh; };int getID(int x, long long w) {return x < 0 ? (x 1ll) / w - 1 : x / w; }struct HashTable* query(struct HashTable* hashTable, int x) {struct HashTable* tmp;HASH_F…

leetcode每日一题-3101 交替子数组计数

暴力遍历&#xff1a;看起来像是回溯,实际上就是递归 class Solution { private:long long _res 0; public:long long countAlternatingSubarrays(vector<int>& nums) {backtrack(nums, 0);return _res;}void backtrack(vector<int>& nums, long long st…

查询某个县区数据,没有的数据用0补充。

加油&#xff0c;新时代打工人&#xff01; 思路&#xff1a; 先查出有数据的县区&#xff0c;用县区编码判断&#xff0c;不存在县区里的数据。然后&#xff0c;用union all进行两个SQL拼接起来。 SELECTt.regionCode,t.regionName,t.testNum,t.sampleNum,t.squareNum,t.crop…

普中51单片机:数码管显示原理与实现详解(四)

文章目录 引言数码管的结构数码管的工作原理静态数码管电路图开发板IO连接图代码演示 动态数码管实现步骤数码管驱动方式电路图开发板IO连接图真值表代码演示1代码演示2代码演示3 引言 数码管&#xff08;Seven-Segment Display&#xff09;是一种常见的显示设备&#xff0c;广…

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类

Visual studio 2023下使用 installer projects 打包C#程序并创建 CustomAction 类 1 安装Visual studio 20203,并安装插件1.1 下载并安装 Visual Studio1.2 步骤二:安装 installer projects 扩展插件2 创建安装项目2.1 创建Windows安装项目2.2 新建应用程序安装文件夹2.3 添加…

A Threat Actors 出售 18 万名 Shopify 用户信息

BreachForums 论坛成员最近发布了涉及 Shopify 的重大数据泄露事件。 据报道&#xff0c;属于近 180,000 名用户的敏感数据遭到泄露。 Shopify Inc. 是一家总部位于安大略省渥太华的加拿大公司。 开发和营销同名电子商务平台、Shopify POS 销售点系统以及专用于企业的营销工…

SQL脚本初始化数据

创建或选择某个数据库&#xff0c;运行窗口输入&#xff1a;source,再拖入文件&#xff0c;回车即可&#xff1b; 虽然也可以使用图形化工具初始化数据&#xff0c;但是他会有内存限制&#xff0c;也就是较大的sql文件不可以初始化&#xff0c;而运行窗口没有sql文件大小限制&…

本周23个Github有趣项目llama-agents等

23个Github有趣的项目、工具和库 1、Positron 下一代数据科学 IDE。 您使用 VS Code 进行数据科学&#xff08;Python 或 R&#xff09;&#xff0c;但希望它包含专用控制台、变量窗格、数据浏览器和其他用于特定数据工作的功能。您使用 Jupyterlab 进行数据科学&#xff08;…

python读取csv出错怎么解决

Python用pandas的read_csv函数读取csv文件。 首先&#xff0c;导入pandas包后&#xff0c;直接用read_csv函数读取报错OSError&#xff0c;如下&#xff1a; 解决方案是加上参数&#xff1a;enginepython。 运行之后没有报错&#xff0c;正在我欣喜之余&#xff0c;输出一下d…

centos7部署mysql8.0

1.安装MySQL的话会和MariaDB的文件冲突&#xff0c;所以需要先卸载掉MariaDB。查看是否安装mariadb rpm -qa | grep mariadb 2. 卸载mariadb rpm -e --nodeps 查看到的文件名 3.下载MySQL安装包 MySQL官网下载地址: MySQL :: Download MySQL Community Serverhttps://dev.mys…

19.JWT

1►JWT博客推荐 阮老师讲得很好了&#xff0c;网址如下&#xff1a; http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html 2►ry是怎么践行JWT的呢&#xff1f; 问题一&#xff1a;不登录的时候有token吗&#xff1f; 答&#xff1a;没有&#xff0c;所…

blender 纹理绘制-贴花方式

贴画绘制-1分钟blender_哔哩哔哩_bilibili小鸡老师的【Blender风格化角色入门教程】偏重雕刻建模https://www.cctalk.com/m/group/90420100小鸡老师最新的【风格化角色全流程进阶教程】偏重绑定。早鸟价进行中&#xff01;欢迎试听https://www.cctalk.com/m/group/90698829, 视…

Splunk Enterprise 中的严重漏洞允许远程执行代码

Splunk 是搜索、监控和分析机器生成大数据的软件领先提供商&#xff0c;为其旗舰产品 Splunk Enterprise 发布了紧急安全更新。 这些更新解决了几个构成重大安全风险的关键漏洞&#xff0c;包括远程代码执行 (RCE) 的可能性。 受影响的版本包括 * 9.0.x、9.1.x 和 9.2.x&…

ARM架构和Intel x86架构

文章目录 1. 处理器架构 2. ARM架构 3. Intel x86架构 4. 架构对比 1. 处理器架构 处理器架构是指计算机处理器的设计和组织方式&#xff0c;它决定了处理器的性能、功耗和功能特性。处理器架构影响着从计算机系统的硬件设计到软件开发的各个方面。在现代计算技术中&#…