跟学视频

1.自定义控件封装

    1. 添加新文件 -  Qt – 设计师界面类  (.h  .cpp  .ui)
    2. .ui中 设计 QSpinBox和QSlider 两个控件
    3. Widget中使用自定义控件,拖拽一个Widget,点击提升为,点击添加,点击提升
    4. 实现功能,改变数字,滑动条跟着移动 ,信号槽监听。
    5. 提供 getNum  和 setNum对外接口
smallwidget.cpp


    //QSpinBox移动 QSplider跟着移动,因为这个方法是valueChanged重载的,所以需要定义函数指针
    void (QSpinBox:: * spSignal )(int) = &QSpinBox::valueChanged;//函数指针
    connect(ui->spinBox, spSignal, ui->horizontalSlider ,&QSlider::setValue);

    //Qslider滑动 QspinBox跟着改变
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);


//设置数字
void SmallWidget::setNum(int num)
{
    ui->spinBox->setValue(num);
}

//获取数字
int SmallWidget::getNum()
{
    return ui->spinBox->value();
}
    //点击获取 获取当前控件的值
    connect(ui->btn_get,&QPushButton::clicked,[=](){
        qDebug() << ui->widget->getNum();

    });

    //设置到一半
    connect(ui->btn_set,&QPushButton::clicked,[=](){
        ui->widget->setNum(50);
    });

2.Qt中的事件

将标准控件提升为自定义类

    1. 鼠标事件
    2. 鼠标进入事件  enterEvent
    3. 鼠标离开事件  leaveEvent
    4. 鼠标按下   mousePressEvent ( QMouseEvent  ev)
    5. 鼠标释放   mouseReleaseEvent
    6. 鼠标移动   mouseMoveEvent
    7. ev->x() x坐标  ev->y() y坐标
    8. ev->button() 可以判断所有按键 Qt::LeftButton  Qt::RightButton
    9. ev->buttons()判断组合按键  判断move时候的左右键  结合 & 操作符
    10. 格式化字符串  QString( “ %1  %2 ” ).arg( 111 ).arg(222)
    11. 设置鼠标追踪    setMouseTracking(true);
myLabel::myLabel(QWidget *parent)
    : QLabel{parent}
{
    //设置鼠标追踪
    setMouseTracking(true);

}

//鼠标进入事件
void myLabel::enterEvent(QEvent *event)
{
    // qDebug() << "鼠标进入了";
}

//鼠标离开事件
void myLabel::leaveEvent(QEvent *)
{
    // qDebug() << "鼠标离开了了";
}
//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button() == Qt::LeftButton)//button(记录的是瞬间状态)
    {
        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)
{
    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)//buttons(记录状态事件) & 且的关系 才能执行
    // {
        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;
    // }
}

3.定时器

    1. 利用事件 void  timerEvent ( QTimerEvent * ev)
    2. 启动定时器 startTimer( 1000) 毫秒单位
    3. timerEvent 的返回值是定时器的唯一标示  可以和ev->timerId 做比较
Widget.h

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();


    //重写定时器事件
    void timerEvent(QTimerEvent *);

    int id1;//定时器1的标识符
    int id2;//定时器2的标识符

private:
    Ui::Widget *ui;
};

Widget.cpp

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    id1 = startTimer(1000); //参数1 间隔(ms)
    id2 = startTimer(2000);


    //QTimer类的使用 Qt中写好的类,直接调用
    QTimer * timer = new QTimer(this);
    timer->start(500);

    connect(timer,&QTimer::timeout,[=](){//发送信号  timeout 

        static int num=1;
        ui->label_4->setText(QString::number(num++));

    });

    connect(ui->btn,&QPushButton::clicked,[=](){
        timer->stop();

    });
}

void Widget::timerEvent(QTimerEvent * ev)
{
    if(ev->timerId() == id1)
    {
        static int num=1;
        ui->label_2->setText(QString::number(num++));
    }

    if(ev->timerId() == id2)
    {
        static int num2=1;
        ui->label_3->setText(QString::number(num2++));
    }
}

4.事件分发器与事件过滤器

    1. 用途:用于事件的分发
    2. 也可以做拦截操作,不建议
    3. bool event( QEvent * e);
    4. 返回值 如果是true 代表用户处理这个事件,不向下分发了
    5. e->type() == 鼠标按下 …
bool myLabel::event(QEvent *e)
{
    //如果是鼠标按下,在event事件分发中做拦截操作
    if(e->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent * ev = static_cast<QMouseEvent *>(e);//类型转换
        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;//true代表用户处理这个事件 不向下分发
    }

    //其他事件交给父类处理 默认处理
    return QLabel::event(e);
}
widget.cpp
  
Widget::Widget(QWidget *parent)

  //给Label安装一个事件过滤器
    //步骤1 安装事件过滤器 要通过Widget给label安装事件过滤器
    ui->label->installEventFilter(this);

//步骤2 重写eventFilter事件
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    if(obj == ui->label)
    {
        if(e->type() == QEvent::MouseButtonPress)
        {
            QMouseEvent * ev = static_cast<QMouseEvent *>(e);//类型转换
            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;

            return true;//true代表用户处理这个事件 不向下分发
        }
    }
    
    //其他事件交给父类处理
    return QWidget::eventFilter(obj,e);
}

 5.QPainter 绘图

    1. 绘图事件  void paintEvent()
    2. 声明一个画家对象  QPainter  painter(this)  this指定绘图设备
    //实例化画家对象 this指的是绘图设备
    QPainter painter(this);

    //设置画笔
    QPen pen(QColor(0,0,255));
    pen.setWidth(3);
    pen.setStyle(Qt::DotLine);
    //让画家拿笔
    painter.setPen(pen);


    //设置画刷
    QBrush brush(Qt::cyan);
    brush.setStyle(Qt::Dense7Pattern);
    painter.setBrush(brush);

    //画线
    painter.drawLine(QPoint(0,0),QPoint(200,200));

    //画圆
    painter.drawEllipse(QPoint(100,100),50,50);

    //画矩形
    painter.drawRect(QRect(100,0,50,50));

    //画文字
    painter.drawText(QRect(0,200,300,50),"好好学习,天天向上");

    QPainter painter(this);

    painter.drawEllipse(QPoint(100,50),50,50);
    //设置 抗锯齿能力
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawEllipse(QPoint(200,50),50,50);

    //画矩形
    painter.drawRect(QRect(20,20,50,50));
    //移动画家
    painter.translate(100,0);
    //保存画家状态
    painter.save();
    painter.drawRect(QRect(20,20,50,50));

    painter.translate(100,0);
    //还原画家保存状态
    painter.restore();
    painter.drawRect(QRect(20,20,50,50));
    
Widget::Widget(QWidget *parent)
{
    connect(ui->pushButton,&QPushButton::clicked,[=](){

        posX+=20;

        //如果要手动调用绘图事件,用update更新
        update();
    });
}

//绘图事件
void Widget::paintEvent(QPaintEvent *)
{
    //利用画家画资源文件
    QPainter painter(this);

    if(posX > this->width())
    {
        posX=0;
    }
    painter.drawPixmap(posX,0,QPixmap(":/Image/Luffy.png"));
}  

6.绘图设备

    1. QPixmap 对不同平台做了显示的优化
      1. QPixmap pix( 300,300)
      2. pix.fill( 填充颜色 )
      3. 利用画家 往pix上画画  QPainter painter( & pix)
      4. 保存  pix.save( “路径”)
    2. Qimage 可以对像素进行访问
      1. 使用和QPixmap差不多 QImage img(300,300,QImage::Format_RGB32);
      2. 其他流程和QPixmap一样
      3. 可以对像素进行修改 img.setPixel(i,j,value);
    3. QPicture  记录和重现 绘图指令
      1. QPicture pic
      2. painter.begin(&pic);
      3. 保存 pic.save( 任意后缀名 )
      4. 重现 利用画家可以重现painter.drawPicture(0,0,pic);
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);


    //Pixmap 绘图设备 专门为平台做了显示优化
    QPixmap pix(300,300);

    //填充颜色
    pix.fill(Qt::white);
    //声明画家
    QPainter painter(&pix);
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(100,100),50,50);

    //保存
    pix.save("C:\\Users\\16385\\Desktop\\pix.png");


    //QImage绘图设备  可以对像素点进行访问
    QImage img(300,300,QImage::Format_ARGB32);

    img.fill(Qt::white);

    QPainter painter(&img);
    painter.setPen(QPen(Qt::green));
    painter.drawEllipse(QPoint(100,100),50,50);

    //保存
    img.save("C:\\Users\\16385\\Desktop\\img.png");


    //QPicture 绘图设备 可以记录和重现绘图指令
    QPicture pic;
    QPainter painter;

    painter.begin(&pic);//开始往pic上画
    painter.setPen(QPen(Qt::cyan));
    painter.drawEllipse(QPoint(100,100),50,50);
    painter.end();//结束画画

    //保存到磁盘
    pic.save("C:\\Users\\16385\\Desktop\\pic.new");


}
void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    //利用QImage对像素点进行更改

    QImage img;
    img.load(":/Image/Luffy.png");

    //修改像素点
    for(int i=50;i<100;i++)
    {
        for(int j=50;j<100;j++)
        {
            QRgb value = qRgb(255,0,0);
            img.setPixel(i,j,value);
        }
    }

    painter.drawImage(0,0,img);

    //重现绘图指令
    QPicture pic;
    pic.load("C:\\Users\\16385\\Desktop\\pic.new");
    painter.drawPicture(0,0,pic);
}

7.QFile读写操作和文件信息获取

    1. QFile进行读写操作
    2. QFile file( path 文件路径)
      1. file.open(打开方式) QIODevice::readOnly
      2. 全部读取  file.readAll()   按行读  file.readLine()  atend()判断是否读到文件尾
      3. 默认支持编码格式 utf-8
      4. 利用编码格式类 指定格式 QTextCodeC
      5. QTextCodec * codec = QTextCodec::codecForName("gbk");
      6. //ui->textEdit->setText( codec->toUnicode(array)  );
      7. 文件对象关闭 close
      1. file.open( QIODevice::writeOnly  / Append)
      2. file.write(内容)
      3. file.close 关闭
   //点击选取文件,弹出文件对话框
    connect(ui->pushButton,&QPushButton::clicked,[=](){

        QString path = QFileDialog::getOpenFileName(this,"打开文件","D:\\Qtproject\\Day3");

        //将路径放到LineEdit中
        ui->lineEdit->setText(path);

        //编码格式类   转换为gbk格式
        // QTextCodec * codec = QTextCodec::codecForName("gbk");

        //读取内容 放到textEdit中
        //QFile 默认的编码格式是utf-8
        QFile file(path);//参数就是读取的路径

        //设置打开方式
        file.open(QIODevice::ReadOnly);
        
        //整体读
        // QByteArray array = file.readAll();

        QByteArray array;//按行读
        while( !file.atEnd() )
        {
            array += file.readLine();
        }


        //将读取的数据 放到textEdit中
        //utf-8格式
        ui->textEdit->setText(array);
        //gbk格式
        // ui->textEdit->setText(codec->toUnicode(array));

        file.close();

        //写文件
        file.open(QIODevice::Append);
        file.write("啊啊啊啊");
        file.close();


        QFileInfo info(path);

        qDebug() << "文件大小:" << info.size() <<"后缀名:" << info.suffix() 
                 << "文件名:" << info.fileName() <<"文件路径"<<info.filePath();
        qDebug() << "创建日期:" << info.created();//完整日期信息
        qDebug() << "创建日期:" << info.created().toString("yyyy/MM/dd hh:mm:ss");
        qDebug() << "最后修改日期" <<info.lastModified().toString("yyyy/MM/dd hh:mm:ss");

    });

8.qt多线程

链接

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐