查看: 1080|回复: 0

[分享] 【经验分享】i.MX6ULL开发:嵌入式Qt-动手编写并运行自己的...

[复制链接]
  • TA的每日心情
    开心
    2020-12-18 12:56
  • 签到天数: 55 天

    [LV.5]常住居民I

    70

    主题

    220

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    1583
    最后登录
    2024-4-19
    发表于 2022-8-31 17:31:11 | 显示全部楼层 |阅读模式
    上篇文章介绍了如何搭建在Linux开发板中搭建Qt的运行环境,并测试了Qt自带的例程。
    本篇,来介绍如何自己编写一个Qt程序,并将编译结果放到Linux开发板中运行。
    1 Windows上编写Qt程序
    因为Qt是支持跨平台的,所以我们可以先在Windows平台上编写和查看Qt的运行效果,然后再通过交叉编译,编译出ARM Linux平台的可执行文件,最终放到开发板中查看运行结果。
    Windows上需要安装Qt Creator软件来开发Qt程序,该软件的安装过程,和大多数软件的安装过程都差不多,在此不再演示安装过程。
    下面介绍如何创建一个Qt工程。
    1.1 新建Qt工程
    Qt Creator本质也是一个集成开发环境,与Visual Studio之类的创建工程的流程类似,其软件界面如下:
    图片 1.png
    创建工程,选择左上角菜单中的“文件”->"新建文件或项目",弹出如下窗口,然后默认选择Qt Widgets Application,然后右下加点击“Choose"按键:
    图片 2.png
    出现选择项目工程的存放位置,然后再下一步:
    图片 3.png
    这里会用到Visual Studio中的一些功能,默认即可,然后下一步:
    图片 4.png
    然后要选择类信息,基类里可选的有QMainWindow、QWidget和QDialog,这里我们选择QWidget。
    下面还有一个”创建界面“的勾选框,那个是用来通过图形化的方式设计显示界面,本篇暂用不到,先取消勾选,然后点下一步
    图片 5.png
    到这里,Qt工程就创建好了,点完成:
    图片 6.png
    创建的Qt工程如下,主要包含4个文件:
    • clock.pro:Qt工程的配置文件
    • main.cpp:主程序
    • widget.cpp:窗口程序
    • widget.h:窗口程序的头文件

    图片 7.png

    1.2 代码编写(时钟程序)Widget的构造函数
    1. Widget::Widget(QWidget *parent)
    2.    : QWidget(parent)
    3. {
    4.    QTimer *timer = new QTimer(this);
    5.    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    6.    timer->start(1000);

    7.    setWindowTitle(tr("Clock"));
    8.    setMinimumSize(200, 200); //设置最小尺寸
    9. }
    复制代码
    首先创建了一个Qt的定时器,设置超时时间为1s(1000ms),超时时间到,更新表盘的显示。
    第2行是Qt中最常用的信号和槽机制:
    1. connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    复制代码
    信号和槽,简单的立即,就是信号SIGNAL出现后(1s定时器超时),触发槽SLOT函数执行(更新表盘的显示)
    界面设计
    时钟程序中的表盘,表针等,都是通过画图的方式实现的,具体的代码如下:
    1. void Widget::paintEvent(QPaintEvent *event)
    2. {
    3.    int side = qMin(width(), height());
    4.    QTime time = QTime::currentTime();

    5.    QPainter painter(this);
    6.    painter.setRenderHint(QPainter::Antialiasing);
    7.    painter.translate(width()/2, height()/2); //画图的基准位置
    8.    painter.scale(side/200.0, side/200.0); //随窗口尺寸自动缩放

    9.    //表盘
    10.    for (int i=0; i<PANEL_RADIUS_NUM; i++)
    11.    {
    12.        QBrush brush(stPanelParaArr[i].color);
    13.        QPen pen(stPanelParaArr[i].color);
    14.        painter.setBrush(brush);
    15.        painter.setPen(pen);
    16.        painter.drawEllipse(-stPanelParaArr[i].radius, -stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius);
    17.    }

    18.    //小时的表针
    19.    painter.setPen(Qt::NoPen);
    20.    painter.setBrush(hourColor);

    21.    painter.save();
    22.    painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
    23.    painter.drawConvexPolygon(hourHand, 3);
    24.    painter.restore();

    25.    //小时的刻度
    26.    painter.setPen(hourColor);
    27.    for (int i = 0; i < 12; ++i)
    28.    {
    29.        painter.rotate(30.0);
    30.        painter.drawLine(PANEL_RADIUS3-6, 0, PANEL_RADIUS3, 0);
    31.        QFont font("TimesNewRoman", HOUR_NUM_SIZE);
    32.        painter.setFont(font);
    33.        painter.drawText(-HOUR_NUM_SIZE, -(CLOCK_RADIUS-15), 2*HOUR_NUM_SIZE, 2*HOUR_NUM_SIZE, Qt::AlignHCenter, QString::number(i+1));
    34.    }

    35.    //分钟的表针
    36.    painter.setPen(Qt::NoPen);
    37.    painter.setBrush(minuteColor);

    38.    painter.save();
    39.    painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
    40.    painter.drawConvexPolygon(minuteHand, 3);
    41.    painter.restore();

    42.    painter.setPen(minuteColor);
    43.    for (int j = 0; j < 60; ++j)
    44.    {
    45.        if ((j % 5) != 0)
    46.        {
    47.            painter.drawLine(PANEL_RADIUS3-4, 0, PANEL_RADIUS3, 0);
    48.        }
    49.        painter.rotate(6.0);
    50.    }

    51.    //秒钟的表针
    52.    painter.setPen(Qt::NoPen);
    53.    painter.setBrush(secondColor);

    54.    painter.save();
    55.    painter.rotate(6.0 * time.second());
    56.    painter.drawConvexPolygon(secondHand, 3);
    57.    painter.restore();

    58.    painter.end();
    59. }
    复制代码
    第2句:
    1. QTime time = QTime::currentTime();
    复制代码
    是来获取系统的当前时间。
    1.3 编译运行
    现在Windows平台中编译运行,查看效果:
    图片 8.png
    该时钟是可以根据窗口大小的变化,自动进行放到或缩小显示的:
    图片 9.png
    2 Ubuntu中交叉编译Qt
    Windows中测试通过后,就需要编译出能够在ARM平台运行的可执行程序了,这里需要在Ubuntu中进行编译。
    2.1 复制源文件到Ubuntu中
    将Windows中的QT工程源码,复制到Ubuntu中,注意.user文件是不需要的,这个是Windows平台的编译配置。
    图片 10.png
    复制到Ubuntu中的合适位置:
    图片 11.png
    2.2 交叉编译
    编译ARM平台的Qt程序,需要使用ARM平台的编译工具链。
    上篇文章,在搭建Qt环境,编译Qt源码时,已经生成了ARM平台的Qt编译工具链,其位置是在上篇文章介绍的make install那一步的安装位置,我的是在”/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/“,这里需要先用到它的qmake工具先自动生成Makefile文件,再通过make指令进行编译。
    首先的使用qmake生成Makefile,进入程序源码目录,执行qmake指令:
    1. /home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake
    复制代码
    成功执行之后,就可以看到自动生成的Makefile文件:
    图片 12.png
    然后执行make指令进行编译:
    1. make
    复制代码
    图片 13.png
    编译完可以看到可执行文件clock。
    我们可以再使用file命令查看该可执行文件的平台信息:
    1. file clock
    复制代码
    图片 14.png
    可以看到该可执行文件是ARM平台的。
    3 Linux开发板中运行Qt程序3.1 复制可执行文件到开发板中
    此次测试,仍然使用的是网络位置挂载根文件系统的方式,通过如下指令将可执行文件复制到根文件系统中(开发板中):
    1. sudo cp clock ~/myTest/nfs/rootfs/myProj/qt/mytest/
    复制代码
    图片 15.png
    3.2 查看开发板中的运行效果
    然后就可以在开发板中执行该程序,查看效果了:
    1. ./clock
    复制代码
    运行效果如下:
    图片 16.png
    由于板子的网络时间还不能正确获取,这里显示的时间其实是不对的,不过表针仍然会1秒1秒的走动。
    4 总结
    本篇详细介绍了如何自己编写一个Qt程序,如何通过交叉编译,最终放到开发板中执行的过程。



    签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-20 14:39 , Processed in 0.115850 second(s), 20 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表