飞凌嵌入式
直播中

fsdzdzy

10年用户 260经验值
擅长:嵌入式技术 控制/MCU opencv
私信 关注
[技术]

【飞凌RK3568开发板试用体验】17-Qt秒表测试

本篇来介绍在OK3568开发板上运行一个编写Qt电子秒表的程序。仿照手机中的秒表,实现一个相同功能的秒表。

1 代码编写

1.1 ui界面设计

使用Qt的UI设计功能设置显示界面:
1.png

注意左边留的空白是给秒表的表盘留的。

1.2 对应按钮的函数

开始按钮的具体业务逻辑代码如下,当首次按下时,checked为true,此时启动timer,记录此时的时间戳,然后将按钮的文字显示为“暂停”,同时将复位和打点按钮置灰,使这两个按钮不能再按下,因为暂停的时候执行复位和打点无意义。

timer每隔一段时间会触发超时,这里ADD_TIME_MSEC设置的是30ms,超时时间到后,编写对应的超时处理函数timeout_slot以及声明对应的信号和槽的处理。

void Widget::on_Btn_Start_toggled(bool checked)
{
    if (checked)
    {
        timer.start(ADD_TIME_MSEC);
        lastTime = QTime::currentTime();//记录时间戳
        ui->Btn_Start->setText("暂停");
        ui->Btn_Reset->setEnabled(false);
        ui->Btn_Hit->setEnabled(true);
    }
    else
    {
        timer.stop();
        ui->Btn_Start->setText("继续");
        ui->Btn_Reset->setEnabled(true);
        ui->Btn_Hit->setEnabled(false);
    }
}
​
connect(&timer, SIGNAL(timeout()), this, SLOT(timeout_slot()));
void Widget::timeout_slot()
{
    //qDebug("hello");
    QTime nowTime = QTime::currentTime();
    time = time.addMSecs(lastTime.msecsTo(nowTime));
    lastTime = nowTime;
    ui->Txt_ShowTime->setText(time.toString("mm:ss.zzz"));
}

超时时间到了之后,计算一些两次的时间差值,然后通过addMSecs函数来累加时间。

1.2.1 复位按钮的处理

复位按钮也是通过右键来调整到槽,注意这里使用****clicked函数即可,因为复位按钮只需要使用它的点击按下功能:

对应的槽函数的具体实现如下:

void Widget::on_Btn_Reset_clicked()
{
    m_iHitCnt = 0;
    timer.stop();
    time.setHMS(0,0,0,0);
    ui->Txt_ShowTime->setText("00:00:00");
    ui->Txt_ShowItem->clear();
​
    ui->Btn_Start->setText("开始");
    ui->Btn_Start->setChecked(false);
    ui->Btn_Reset->setEnabled(false);
    ui->Btn_Hit->setEnabled(false);
}

主要是将时间归零,将显示情况,并将各个按钮的显示状态复位为默认显示状态。

1.2.2 打点按钮的处理

打点按钮与复位按钮一样,也是只使用****clicked函数即可,对应的槽函数的具体实现如下:

void Widget::on_Btn_Hit_clicked()
{
    QString temp;
    m_iHitCnt++;
    temp.sprintf("--计次 %d--", m_iHitCnt);
    ui->Txt_ShowItem->setFontPointSize(9);
    ui->Txt_ShowItem->append(temp);
    ui->Txt_ShowItem->setFontPointSize(12);
    ui->Txt_ShowItem->append(time.toString("[mm:ss.zzz]"));
}

打点功能用于在秒表的运行过程中,记录不同名次的时间,并显示在右侧的文本显示框中。

这里通过setFontPointSize函数来设置不同大小的字体显示。

1.3 秒表表盘的实现

通过QPainter画图,实现一个显示秒和分的秒表表盘,具体代码如下:

connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
connect(ui->Btn_Reset, SIGNAL(clicked()), this, SLOT(update()));
​
void Widget::paintEvent(QPaintEvent *event)
{
    int side = qMin(width(), height());
    //QTime time = QTime::currentTime();
​
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width()/4, height()/2); //画图的基准位置
    painter.scale(side/300.0, side/300.0); //随窗口尺寸自动缩放//表盘(3个同心圆)
    for (int i=0; i<PANEL_RADIUS_NUM; i++)
    {
        QBrush brush(stPanelParaArr[i].color);
        QPen pen(stPanelParaArr[i].color);
        painter.setBrush(brush);
        painter.setPen(pen);
        painter.drawEllipse(-stPanelParaArr[i].radius, -stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius);
    }
​
    //秒的刻度
    painter.setPen(secondColor);
    for (int i = 0; i < 60; i++)
    {
        if ((i % 5) == 0)
        {
            painter.drawLine(PANEL_RADIUS3-8, 0, PANEL_RADIUS3, 0);
            QFont font("TimesNewRoman", SEC_NUM_SIZE);
            painter.setFont(font);
            painter.drawText(-SEC_NUM_SIZE, -(CLOCK_RADIUS-15), 2*SEC_NUM_SIZE, 2*SEC_NUM_SIZE, Qt::AlignHCenter, QString::number(i==0? 60 : i));
        }
        else
        {
            painter.drawLine(PANEL_RADIUS3-5, 0, PANEL_RADIUS3, 0);
        }
        //秒再细分5个格
        for (int j = 0; j < 5; j++)
        {
            painter.rotate(6.0/5);
            if (j != 4)
            {
                painter.drawLine(PANEL_RADIUS3-2, 0, PANEL_RADIUS3, 0);
            }
        }
    }
​
    //分钟的刻度
    painter.setPen(minuteColor);
    for (int k = 0; k < 30; k++)
    {
        if ((k % 5) == 0)
        {
            painter.rotate(-90.0);
            painter.drawLine(PANEL_RADIUS4-8, 0, PANEL_RADIUS4, 0);
            painter.rotate(90.0);
​
            QFont font("TimesNewRoman", MIN_NUM_SIZE);
            painter.setFont(font);
            painter.drawText(-MIN_NUM_SIZE, -(PANEL_RADIUS4-10), 2*MIN_NUM_SIZE, 2*MIN_NUM_SIZE, Qt::AlignHCenter, QString::number(k==0? 30 : k));
        }
        else
        {
            painter.rotate(-90.0);
            painter.drawLine(PANEL_RADIUS4-4, 0, PANEL_RADIUS4, 0);
            painter.rotate(90.0);
        }
        painter.rotate(12.0);
    }
​
    //分钟的表针
    painter.setPen(Qt::NoPen);
    painter.setBrush(minuteColor);
    painter.save();
    painter.rotate(12.0 * (time.minute() + time.second() / 60.0));
    painter.drawConvexPolygon(minuteHand, 3);
    painter.restore();
​
    //秒钟的表针
    painter.setPen(Qt::NoPen);
    painter.setBrush(secondColor);
    painter.save();
    //painter.rotate(6.0 * time.second());
    painter.rotate(6.0 * (time.second()+time.msec()/1000.0));
    painter.drawConvexPolygon(secondHand, 3);
    painter.restore();
​
    painter.end();
}

主要修改是将之前的小时显示去掉,并改为两个时间环:外圈秒环和内圈分环,秒环的范围是0-60秒,分环的范围是0-30分。

秒表表盘的显示效果如下:

2.png

2 编译运行

在Ubuntu中使用RK3568的编译工具链进行交叉编译,然后将编译文件放到OK3568板子中运行。

运行效果如下:

3.png

3 总结

本篇实现了在OK3568开发板上运行一个编写Qt电子秒表的程序。可以实现打点,暂停,复位等功能。

更多回帖

发帖
×
20
完善资料,
赚取积分