加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1 Windows上編寫(xiě)Qt程序
    • 2 Ubuntu中交叉編譯Qt
    • 3 Linux開(kāi)發(fā)板中運(yùn)行Qt程序
    • 4 總結(jié)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

嵌入式Qt-動(dòng)手編寫(xiě)并運(yùn)行自己的第1個(gè)ARM-Qt程序

2022/08/01
1808
閱讀需 5 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

上篇文章:嵌入式Linux-Qt環(huán)境搭建,介紹了如何搭建在Linux開(kāi)發(fā)板中搭建Qt的運(yùn)行環(huán)境,并測(cè)試了Qt自帶的例程。

本篇,來(lái)介紹如何自己編寫(xiě)一個(gè)Qt程序,并將編譯結(jié)果放到Linux開(kāi)發(fā)板中運(yùn)行。

1 Windows上編寫(xiě)Qt程序

因?yàn)镼t是支持跨平臺(tái)的,所以我們可以先在Windows平臺(tái)上編寫(xiě)和查看Qt的運(yùn)行效果,然后再通過(guò)交叉編譯,編譯出ARM Linux平臺(tái)的可執(zhí)行文件,最終放到開(kāi)發(fā)板中查看運(yùn)行結(jié)果。

Windows上需要安裝Qt Creator軟件來(lái)開(kāi)發(fā)Qt程序,該軟件的安裝過(guò)程,和大多數(shù)軟件的安裝過(guò)程都差不多,在此不再演示安裝過(guò)程。

下面介紹如何創(chuàng)建一個(gè)Qt工程。

1.1 新建Qt工程

Qt Creator本質(zhì)也是一個(gè)集成開(kāi)發(fā)環(huán)境,與Visual Studio之類(lèi)的創(chuàng)建工程的流程類(lèi)似,其軟件界面如下:

創(chuàng)建工程,選擇左上角菜單中的“文件”->"新建文件或項(xiàng)目",彈出如下窗口,然后默認(rèn)選擇Qt Widgets Application,然后右下加點(diǎn)擊“Choose"按鍵:

出現(xiàn)選擇項(xiàng)目工程的存放位置,然后再下一步:

這里會(huì)用到Visual Studio中的一些功能,默認(rèn)即可,然后下一步:

然后要選擇類(lèi)信息,基類(lèi)里可選的有QMainWindow、QWidget和QDialog,這里我們選擇QWidget。

下面還有一個(gè)”創(chuàng)建界面“的勾選框,那個(gè)是用來(lái)通過(guò)圖形化的方式設(shè)計(jì)顯示界面,本篇暫用不到,先取消勾選,然后點(diǎn)下一步

到這里,Qt工程就創(chuàng)建好了,點(diǎn)完成:

創(chuàng)建的Qt工程如下,主要包含4個(gè)文件:

  • clock.pro:Qt工程的配置文件main.cpp:主程序widget.cpp:窗口程序widget.h:窗口程序的頭文件

 

1.2 代碼編寫(xiě)(時(shí)鐘程序)

Widget的構(gòu)造函數(shù)

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);

    setWindowTitle(tr("Clock"));
    setMinimumSize(200, 200); //設(shè)置最小尺寸
}

首先創(chuàng)建了一個(gè)Qt的定時(shí)器,設(shè)置超時(shí)時(shí)間為1s(1000ms),超時(shí)時(shí)間到,更新表盤(pán)的顯示。

第2行是Qt中最常用的信號(hào)和槽機(jī)制:

connect(timer, SIGNAL(timeout()), this, SLOT(update()));

信號(hào)和槽,簡(jiǎn)單的立即,就是信號(hào)SIGNAL出現(xiàn)后(1s定時(shí)器超時(shí)),觸發(fā)槽SLOT函數(shù)執(zhí)行(更新表盤(pán)的顯示)

界面設(shè)計(jì)

時(shí)鐘程序中的表盤(pán),表針等,都是通過(guò)畫(huà)圖的方式實(shí)現(xiàn)的,具體的代碼如下:

void Widget::paintEvent(QPaintEvent *event)
{
    int side = qMin(width(), height());
    QTime time = QTime::currentTime();

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(width()/2, height()/2); //畫(huà)圖的基準(zhǔn)位置
    painter.scale(side/200.0, side/200.0); //隨窗口尺寸自動(dòng)縮放

    //表盤(pán)
    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);
    }

    //小時(shí)的表針
    painter.setPen(Qt::NoPen);
    painter.setBrush(hourColor);

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

    //小時(shí)的刻度
    painter.setPen(hourColor);
    for (int i = 0; i < 12; ++i)
    {
        painter.rotate(30.0);
        painter.drawLine(PANEL_RADIUS3-6, 0, PANEL_RADIUS3, 0);
        QFont font("TimesNewRoman", HOUR_NUM_SIZE);
        painter.setFont(font);
        painter.drawText(-HOUR_NUM_SIZE, -(CLOCK_RADIUS-15), 2*HOUR_NUM_SIZE, 2*HOUR_NUM_SIZE, Qt::AlignHCenter, QString::number(i+1));
    }

    //分鐘的表針
    painter.setPen(Qt::NoPen);
    painter.setBrush(minuteColor);

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

    painter.setPen(minuteColor);
    for (int j = 0; j < 60; ++j)
    {
        if ((j % 5) != 0)
        {
            painter.drawLine(PANEL_RADIUS3-4, 0, PANEL_RADIUS3, 0);
        }
        painter.rotate(6.0);
    }

    //秒鐘的表針
    painter.setPen(Qt::NoPen);
    painter.setBrush(secondColor);

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

    painter.end();
}

第2句:

QTime time = QTime::currentTime();

是來(lái)獲取系統(tǒng)的當(dāng)前時(shí)間。

1.3 編譯運(yùn)行

現(xiàn)在Windows平臺(tái)中編譯運(yùn)行,查看效果:

該時(shí)鐘是可以根據(jù)窗口大小的變化,自動(dòng)進(jìn)行放到或縮小顯示的:

 

2 Ubuntu中交叉編譯Qt

Windows中測(cè)試通過(guò)后,就需要編譯出能夠在ARM平臺(tái)運(yùn)行的可執(zhí)行程序了,這里需要在Ubuntu中進(jìn)行編譯。

2.1 復(fù)制源文件到Ubuntu中

將Windows中的QT工程源碼,復(fù)制到Ubuntu中,注意.user文件是不需要的,這個(gè)是Windows平臺(tái)的編譯配置。

復(fù)制到Ubuntu中的合適位置:

 

2.2 交叉編譯

編譯ARM平臺(tái)的Qt程序,需要使用ARM平臺(tái)的編譯工具鏈。

上篇文章,在搭建Qt環(huán)境,編譯Qt源碼時(shí),已經(jīng)生成了ARM平臺(tái)的Qt編譯工具鏈,其位置是在上篇文章介紹的make install那一步的安裝位置,我的是在”/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/“,這里需要先用到它的qmake工具先自動(dòng)生成Makefile文件,再通過(guò)make指令進(jìn)行編譯。

首先的使用qmake生成Makefile,進(jìn)入程序源碼目錄,執(zhí)行qmake指令:

/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake

成功執(zhí)行之后,就可以看到自動(dòng)生成的Makefile文件:

然后執(zhí)行make指令進(jìn)行編譯:

make

 

編譯完可以看到可執(zhí)行文件clock。

我們可以再使用file命令查看該可執(zhí)行文件的平臺(tái)信息:

file clock

 

可以看到該可執(zhí)行文件是ARM平臺(tái)的。

3 Linux開(kāi)發(fā)板中運(yùn)行Qt程序

3.1 復(fù)制可執(zhí)行文件到開(kāi)發(fā)板中

此次測(cè)試,仍然使用的是網(wǎng)絡(luò)位置掛載根文件系統(tǒng)的方式,通過(guò)如下指令將可執(zhí)行文件復(fù)制到根文件系統(tǒng)中(開(kāi)發(fā)板中):

sudo cp clock ~/myTest/nfs/rootfs/myProj/qt/mytest/

 

 

3.2 查看開(kāi)發(fā)板中的運(yùn)行效果

然后就可以在開(kāi)發(fā)板中執(zhí)行該程序,查看效果了:

./clock

運(yùn)行效果如下:

由于板子的網(wǎng)絡(luò)時(shí)間還不能正確獲取,這里顯示的時(shí)間其實(shí)是不對(duì)的,不過(guò)表針仍然會(huì)1秒1秒的走動(dòng)。

4 總結(jié)

本篇詳細(xì)介紹了如何自己編寫(xiě)一個(gè)Qt程序,如何通過(guò)交叉編譯,最終放到開(kāi)發(fā)板中執(zhí)行的過(guò)程。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

控制科學(xué)與工程碩士,日常分享單片機(jī)、嵌入式、C/C++、Linux等學(xué)習(xí)經(jīng)驗(yàn)干貨~