Qt自定义控件封装
步骤
- 添加类 Qt-设计师界面类 .h .cpp .ui
此时就添加成功 - 选择一个QWidget控件,添加到主界面,右击选择
提升为 , . 此时,我们要将1步骤的Qt界面设计类添加进去,选择提升 如果
则说明替换成功
- 设置自定义控件封装内组件之间的联动效果,在.cpp文件中设置
smallWiget::smallWiget(QWidget *parent) :
QWidget(parent),
ui(new Ui::smallWiget)
{
ui->setupUi(this);
void(QSpinBox:: *spinSignal)(int) = &QSpinBox::valueChanged;
connect(ui->spinBox,spinSignal,ui->horizontalSlider,&QSlider::setValue);
connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
- 设置一些接口,供外部去使用 :(在.h文件中声明,在.cpp文件中实现)
class smallWiget : public QWidget
{
Q_OBJECT
public:
explicit smallWiget(QWidget *parent = 0);
void setData(int val);
int getData();
~smallWiget();
private:
Ui::smallWiget *ui;
};
void smallWiget::setData(int val){
ui->spinBox->setValue(val);
}
int smallWiget::getData(){
return ui->spinBox->value();
}
- 外部的简单使用
connect(ui->btn_getValue,&QPushButton::clicked,[=](){
qDebug()<<"当前的数值为:"<< ui->widget->getData();
});
connect(ui->btn_setHalf,&QPushButton::clicked,[=](){
ui->widget->setData(50);
});
- 效果展示
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){
if(e->timerId()==id1){
static int num =1;
ui->label->setText(QString::number(num++));
}else{
static int num2 =10;
ui->label_2->setText(QString::number(num2+=10));
}
}
当我们有多个定时器时,我们可以使用定时器的类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();
注意:两个实现定时器的方法没有优劣之分,按照需求选择合适的就可
事件分发器
bool event(QEvent *e) e->type() 所有Qt中的事件- 事件分发器可以做事件的拦截操作,如果用户进行了拦截,在对应事件里返回true代表自己处理事件
事件过滤器
使用事件过滤器可以做更高级拦截
使用事件过滤器有两步:
- 给对应的控件安装事件过滤器
ui->label->installEventFilter(this);
- 重写eventFilter
bool eventFilter(QObject *watched, QEvent *event);
bool Widget::eventFilter(QObject *watched, QEvent *event){
if(obj==ui->label){
if(event->type()==QEvent::MouseButtonPress){
return true;
}
}
return QWidget::eventFilter(obj,event);
}
绘画
基本绘画
- 绘画方法
void paintEvent(QPaintEvent *event);
- 声明画家
QPainter painter(this);
- 设置画笔
QPen pen(QColor(255,0,0));
pen.setWidth(3);
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
- 设置画刷
QBrush brush(Qt::cyan);
brush.setStyle(Qt::Dense6Pattern);
painter.setBrush(brush);
- 绘制一些基础图形
painter.drawLine(QPoint(0,0),QPoint(100,100));
painter.drawEllipse(QPoint(100,100),50,50);
painter.drawRect(QRect(20,20,50,50));
painter.drawText(QRect(10,200,120,100),"好好学习,天天向上");
- 效果展示
高级绘画设置
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));
painter.translate(QPoint(100,0));
painter.save();
painter.drawRect(QRect(20,20,50,50));
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,[=](){
posX+=20;
update();
});
}
void Widget::paintEvent(QPaintEvent *event){
QPainter painter(this);
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 pix(300,300);
pix.fill(Qt::white);
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 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){
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开发者工具") ;
if(filePath.isEmpty()){
QMessageBox::warning(this,"打开失败","文件路径为空");
return;
}
ui->lineEdit->setText(filePath);
QTextCodec *code = QTextCodec::codecForName("gbk");
QFile file(filePath);
file.open(QIODevice::ReadOnly);
QByteArray arr;
while(!file.atEnd()){
arr += file.readLine();
}
ui->textEdit->setText(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类 利用文件的后缀名,可以做过滤文件的作用(这里不展示)
|