【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…

Python面试题:在 Python 中,如何实现上下文管理器(context manager)?

在 Python 中&#xff0c;实现上下文管理器&#xff08;context manager&#xff09;有两种常见的方法&#xff1a;使用类和使用装饰器&#xff08;contextlib 模块中的 contextmanager 装饰器&#xff09;。上下文管理器用于管理资源&#xff0c;例如文件、网络连接等&#xf…

昇思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…

BiLSTM模型实现

# 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 # 本段代码构建类BiLSTM, 完成初始化和网络结构的搭建 # 总共3层: 词嵌入层, 双向LSTM层, 全连接线性层 import torch import torch.nn as nn# 本函数实现将中文文本映射为…

Android使用HttpURLConnection实现文件上传(包括图片)

1.文件上传完整代码 下面是完整的文件上传代码&#xff0c;复制即可使用。注意要开启子线程运行 public class UploadFileTask {/*** 上传文件到服务器&#xff0c;并返回服务器相应结果* param requestURL 服务器的地址* param imageUri 文件的Uri* param context* return 服…

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

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

只需4500字,带你学习Python中7种基础数据类型!

Python 语言以其简洁、高效和强大的功能&#xff0c;成为了无数开发者和编程爱好者的首选。无论是数据分析、人工智能、网络开发还是自动化脚本&#xff0c;Python 都能以其优雅的语法和丰富的库支持&#xff0c;让编程变得更加简单而有趣。 但正如建造一座大厦需要坚实的地基…

如何借助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 属性和方法…

postgresql日志的配置

postgresql日志的配置 一 常用日志参数设置 1 在哪里做日志 logging_collector = on/off这个参数启用日志收集器,是否将日志重定向至文件中。默认是off。设置需要重启库 log_directory当logging_collector被启用时,这个参数决定日志文件将被在哪个目录下创建。默认是log。设…

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;广…

Java NIO:深入探索非阻塞I/O操作

Java NIO&#xff1a;深入探索非阻塞I/O操作 一、引言 随着网络应用的快速发展&#xff0c;对于高性能I/O操作的需求日益增加。传统的Java I/O模型基于流&#xff08;Stream&#xff09;进行数据传输&#xff0c;采用阻塞式&#xff08;Blocking&#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 添加…

sqlserver 当前时间

sqlserver 当前时间 在 SQL Server 中&#xff0c;获取当前时间有多种方法&#xff0c;以下是一些常用的方法&#xff1a; 使用 GETDATE() 函数&#xff1a; SELECT GETDATE() AS CurrentDateTime 如果你需要更精确的时间&#xff08;包括毫秒&#xff09;&#xff0c;可以使…

数据库SQL Server常用操作:增删改查

文章目录 SQL Server主要特点 常见数据库操作假设tmall_scapler_item_pk是一个主键约束临时表表的连接 SQL Server SQL Server 是由微软&#xff08;Microsoft&#xff09;公司开发的一个关系数据库管理系统&#xff08;RDBMS&#xff09;。它允许企业或组织存储、检索、修改和…

力扣刷题练习 七【34. 在排序数组中查找元素的第一个和最后一个位置】

前言 数组类型题目练习。 练习题 七【34. 在排序数组中查找元素的第一个和最后一个位置】 一、题目阅读 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&…