文章目录
- 自定义控件封装
- 自定义框架
- 定时器
- 第一种方式
- [第二种方式 (推荐)](#第二种方式 (推荐))
- 事件分发器
- QPainter
- 作业
- QPaintDevice绘图设备
- QFile文件读写操作
自定义控件封装
1.创建新文件-Qt-设计师界面类(.h .cpp .ui)
2.以QSpinBox和QSlider为例子。在.ui中设计这两个控件
3.在主ui中添加Widget,并把它升级。
类名称为自己在添加新文件(设计师界面类)写的。
若这个自定义控件经常用到,可以设为全局包含
- 添加两个按钮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中实现这两个函数
自定义框架
1.创建新文件-C/C+±Class,我这里命名为myLable.
2.改3处类名
3.在头文件写函数声明
cpp
//鼠标进入事件
void enterEvent(QEnterEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *);
//鼠标按下
virtual void mousePressEvent(QMouseEvent *ev);
//鼠标释放
virtual void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动
virtual void mouseMoveEvent(QMouseEvent *ev);
4.在源文件实现函数
cpp
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个公有变量
cpp
public:
Widget(QWidget *parent = nullptr);
~Widget();
//重写定时器事件
void timerEvent(QTimerEvent *);
int id1;//定时器1的唯一标识
int id2;//定时器2的唯一标识
private:
Ui::Widget *ui;
};
3.在源文件写函数实现和调用定时器。
cpp
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秒+1
ui->label_2->setText(QString::number(num++));
}
if(ev->timerId() == id2)
{
static int num2 = 1;
//label3 每隔2秒+1
ui->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.在头文件添加函数声明
cpp
//通过event事件分发器 拦截 鼠标按下事件
bool event(QEvent *e);
2.在源文件实现函数
cpp
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.在头文件声明函数
cpp
//绘图事件
void paintEvent(QPaintEvent * );
2.在源文件实现函数
记得要引入类
#include <QPainter>
cpp
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.在头文件声明函数
cpp
//绘图事件
void paintEvent(QPaintEvent * );
2.在源文件函数实现
cpp
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);
}
移动坐标原点
cpp
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.在头文件声明函数和全局变量
cpp
public:
Widget(QWidget *parent = nullptr);
~Widget();
//绘图事件
void paintEvent(QPaintEvent * );
int posX=0;
4.在源文件实现函数
cpp
#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.在源文件实现按钮
cpp
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( 路飞) )
作业
实现路飞的自动移动,即自动连播。
头文件
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent * );
int posX=0;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
源文件
cpp
#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>
cpp
//点击选取文件按钮,弹出文件对话框
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.进行写操作
cpp
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>
在源代码
cpp
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");
}