上篇文章:嵌入式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ò)程。