前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Qt入门系列(三)

Qt入门系列(三)

作者头像
用户9831583
发布2022-06-16 15:25:29
1.1K0
发布2022-06-16 15:25:29
举报
文章被收录于专栏:码出名企路

文章首发在博主知乎


7.自定义控件封装

增加新的sw.ui界面

选装父文件—>添加文件-->Qt--->设计师界面->命名smallWidget(简称sw)

选择sw.ui->选择Spin Box和Horizontal Slider进行水平布局->但此时运行还是原来的w.ui--》想把sw.ui用在原来w.ui上

查看sw.ui的类型widget-》在w.ui上添加Widget控件-》右键选提升为->把类名复制进去-》点击添加-》点击提升--》运行出现!

现在要实现两者同时移动

自己输入空间查找想要的信号和槽函数Public Slots,如子类中没有,查找父类的槽函数

在sw.cpp中添加代码:

代码语言:javascript
复制
    //QSpingBox移动,QSlider跟着移动
    //因为重载,需要写个函数指针
    void(QSpinBox:: *spSignal)(int)=&QSpinBox::valueChanged;
    connect(ui->spinBox,spSignal,ui->horizontalSlider,&QSlider::setValue);

    //反过来
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);

结果显示:

需求:设置数字和获取数字

在w.ui上添加两个按钮push Botton

在sw.h和sw.cpp中设置接口和实现

代码语言:javascript
复制
//设置数组
void SmallWidget::setNum(int num){
    ui->spinBox->setValue(num);
}
//获取数字
int SmallWidget::getNum(){
    return ui->spinBox->value();
}

在w.cpp中进行关联

代码语言:javascript
复制
    //获取到控件当前的值
    connect(ui->get,&QPushButton::clicked,[=](){
        qDebug() << ui->widget->getNum();
    });

    //设置数字
    connect(ui->set,&QPushButton::clicked,[=](){
           ui->widget->setNum(50);
    });

结果显示:

8.事件

8.1.鼠标事件

->ui.上选择一个Label控件

-》父节点新添加一个class Label(简称l)

在l.h和l.cpp中添加实现:

代码语言:javascript
复制
//鼠标进入事件
void Label::enterEvent(QEvent *event)
{
    qDebug()<<"鼠标进入了";
}
//鼠标离开
void Label::leaveEvent(QEvent *)
{
    qDebug()<<"鼠标离开了";
}

注意,此时控件与鼠标没有关联,进行关联

把新建的class l改成继承于QLabel。

在Label控件上右键提升为--》Label,生成即可

结果显示:

此时需要重写鼠标按下,离开等,在l.cpp中继续添加:

代码语言:javascript
复制

//鼠标按下
void Label::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 Label::mouseReleaseEvent(QMouseEvent *ev)
 {
    qDebug()<<"鼠标释放";
 }
//鼠标移动
 void Label::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;
    }
 }

结果显示:

8.2.定时器

需求:定时器加数,每隔1秒中加1

继续上面代码:

在w.cpp中实现

代码语言:javascript
复制

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;//下次不会从1开始类
        ui->label_2->setText(QString::number(num++));

    }

    if(ev->timerId()==id2)
    {
        static int num1=2;//下次不会从1开始类
        ui->lab->setText(QString::number(num1++));
    }
}

结果显示:

另外一种实现方式,大力推荐:

代码语言:javascript
复制
    //类中实现
//定时器第二种方式
     QTimer *timer=new QTimer(this);
     timer->start(500);
     connect(timer,&QTimer::timeout,[=](){
         static int num=1;
         ui->label_3->setText(QString::number(num++));
     });
     //再增加一个就好类
     //点击停止按钮
     connect(ui->pushButton,&QPushButton::clicked,[=](){
         timer->stop();
     });

结果显示:

8.3.事件分发器

概况:

继续上文代码,拦截鼠标按下

在l.cpp中添加:

代码语言:javascript
复制
 bool Label::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;//代表用户自己处理,不向下分发
    }
    //其他事件交给父亲处理
    return QLabel::event(e);
 }

结果显示:

8.4.事件过滤器

概述:

用事件过滤器对鼠标按下进行拦截

在w.cpp中继续

代码语言:javascript
复制
 { //给label1 安装事件过滤器
     //步骤1 :安装时间过滤器
     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;//代表用户自己处理,不向下分发
        }
    }

    //其他默认处理
    return QWidget::eventFilter( obj, e);
}

结果显示:

8.5.绘图事件

新建Q3

在w.cpp中添加代码:

代码语言:javascript
复制
   void Widget::paintEvent(QPaintEvent *)
   {
        //实例化一个画家
       QPainter painter(this);

       //设置画笔
       QPen pen(QColor(255,0,0));
       //设置画笔宽度
       pen.setWidth(3);
       //设置画笔风格
       pen.setStyle(Qt::DotLine);
       painter.setPen(pen);

       //设置化刷,对封闭图像图色
       QBrush brush(QColor(0,255,0));
       //设置化刷风格
       brush.setStyle(Qt::Dense1Pattern);
       //或者枚举的颜色
       QBrush brush1(Qt::cyan);
       //让画家使用化刷
       painter.setBrush(brush1);


       //直线
       painter.drawLine(QPoint(0,0),QPoint(100,100));
       //椭圆
       painter.drawEllipse(QPoint(100,100),50,50);
       //矩形
       painter.drawRect(QRect(100,100,100,100));

       //写字
       painter.drawText(QRect(100,100,100,100),"好好学习,天天向上 ");

   }

结果显示:

8.6.绘图高级设置

将上面注释

将图像进行移动,调色,抗锯齿处理等

在w.cpp中添加代码:

代码语言:javascript
复制
  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));

结果显示:

8.7.手动调用绘图事件

利用画家画资源图片

上面注释

添加资源图片,不多说,前面已经讲过。

在w.cpp中添加代码:

代码语言:javascript
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //点击按钮移动,进行移动
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        posX+=20;
        update();
    });
}

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

         //如果超出屏幕,从0开始
         if(posX >this->width())
         {
             posX=0;
         }
         painter.drawPixmap(posX,0,QPixmap(":/data/05.pgm"));
   }

结果显示:

需求:利用定时器进行自动移动

在w.cpp中添加代码:

代码语言:javascript
复制
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,[=](){
               if(leftToRight)
               {
                   posX+=20;
                           update();
               }
               if(rightToLeft)
               {
                   posX-=20;
                    update();//调用paintEvent函数
               }

          });

}

   void Widget::paintEvent(QPaintEvent *)
   {

       //利用画家画资源文件
         QPainter painter(this);

         //如果超出屏幕,从0开始
         if(posX >this->width())
         {
             posX=this->width();
             rightToLeft=true;
              leftToRight=false;
         }
         if(posX<0)
         {
             posX=0;
             leftToRight=true;
             rightToLeft=false;
         }
         painter.drawPixmap(posX,0,QPixmap(":/data/05.pgm"));
   }

8.8.绘图设备

8.8.1.QPixmap

直接保存到本地

画一个圆保存在本地

在w.cpp中添加代码:

代码语言:javascript
复制
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(50,50),50,50);
    //保存
    pix.save("/home/lyy/yuan.png");

}

保存结果:

8.8.2.QImage

实现1的功能

代码语言:javascript
复制
//QImage绘图设备,可以对像素进行访问
    QImage img(300,300,QImage::Format_RGB32);
    //填充颜色
    img.fill(Qt::white);
    //声明画家
    QPainter painter(&img);
    painter.setPen(QPen(Qt::blue));
    painter.drawEllipse(QPoint(50,50),50,50);
    //保存
    img.save("/home/lyy/blue.png");

需求:加载资源文件,并改变像素值

加载资源图片不能再熟悉类,省略

在w.cpp中添加代码

代码语言:javascript
复制
   void Widget::paintEvent(QPaintEvent *)
   {
       QPainter painter(this);
       QImage img;
       img.load(":/data/01.pgm");
       //修改像素点
       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);

   }

8.8.3.QPicture

主要用来记住代码,重新打开非常见后缀名的图片,别人打不开啊,只能用我的代码打开

在w.cpp中添加代码:

代码语言:javascript
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //QPicture 绘图设备,可以记录和重新绘图指令
    QPicture pic;
    QPainter painter;
    painter.begin(&pic);//开始往pic上画
    painter.setPen(QPen(Qt::cyan));
    painter.drawEllipse(QPoint(150,150),100,100);
    painter.end();//结束画面
    //保存
    pic.save("/home/lyy/pic.zt");

}

   void Widget::paintEvent(QPaintEvent *)
   {

       //重现不能打开的图片
       QPainter painter(this);
       QPicture pic;
       pic.load("/home/lyy/pic.zt");
       painter.drawPicture(0,0,pic);

   }

结果打开了:

9.文件

9.1.QFile读和写

需求:选取文件路径,打开文件

1.ui上选取Line Edit和Push Button水平对齐,再选取Text Edit,三者垂直布局

2.在w.cpp上添加代码

代码语言:javascript
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //点击选取文件按钮,弹出文件对话框
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        QString path=QFileDialog::getOpenFileName(this,"打开文件","/home/lyy/");
        //将路径放入linetext中
        ui->lineEdit->setText(path);

        //编码格式类
        QTextCodec *codec=QTextCodec::codecForName("gbk");
        //读取内容,放入textline中
        //QFile默认格式是utf-8,其他打开是乱码
        QFile file(path);
         //设置打开方式
        file.open(QIODevice::ReadOnly);
        //读取全部
       //  QByteArray array=file.readAll();

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

        //将读取的数据放入
       ui->textEdit->setText(array);

        //ui->textEdit->setText(codec->toUnicode(array));
       //关闭文件
       file.close();

       //对文件进行写操作
       file.open(QIODevice::Append);
       file.write("我是一个程序员");
       file.close();

    });
}

结果显示:

9.2.QFileInfo信息流

需求:读取文件的属性,比如后缀名,修改日期等

在1中代码基础上添加:

代码语言:javascript
复制
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

        //QFileInfo文件信息流
       QFileInfo info(path);
       qDebug()<<"文件大小: "<<info.size()<<"后缀名: "<<info.suffix()<<"文件名: "<<info.fileName();

       //创建日期
       qDebug()<<"创建日期: "<<info.created().toString("yyyy/MM/dd hh:mm:ss");
       qDebug()<<"修改日期: "<<info.lastModified().toString("yyyy/MM/dd hh:mm:ss");

    });
}

结果显示:

笔记如下:

参考:黑马程序员

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 8.事件
  • 8.1.鼠标事件
  • 8.2.定时器
  • 8.3.事件分发器
  • 8.4.事件过滤器
  • 8.5.绘图事件
  • 8.6.绘图高级设置
  • 8.7.手动调用绘图事件
  • 8.8.绘图设备
  • 8.8.1.QPixmap
  • 8.8.2.QImage
  • 8.8.3.QPicture
  • 9.文件
  • 9.1.QFile读和写
  • 9.2.QFileInfo信息流
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档