文章目录
- 自定义控件封装
- 自定义框架
- 定时器
- 第一种方式
- 第二种方式 (推荐)
- 事件分发器
- QPainter
- 基本操作
- 高级设置
- 抗锯齿
- 移动坐标原点
- 画家画资源图片,并实现手动移动
- 作业
- QPaintDevice绘图设备
- QPixmap
- Qimage
- QPicture
- QFile文件读写操作
- QFileInfo文件信息获取
自定义控件封装
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.在头文件写函数声明
//鼠标进入事件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");}