

摘要
由于Qt具有良好的可移植性,在桌面版本中编译运行成功的应用程序,一般只需要用交叉编译工具的qmake重新编译,即可在目标板上运行。执行嵌入式的qmake(别名qmake-arm),重新交叉编译,便可获得嵌入式版本的Qt程序。
文员也能看懂学通的《嵌入式Linux开发教程》正式开始免费连载啦!致远电子微信公众平台【独家首发】。在这个教程中,你看不到自我陶醉的炫技,内容通俗易懂,实用够用为先。本教程凝聚了ZLG致远电子嵌入式工程师的心血,转载请【注明出处】。
1.1.1 菜单栏、工具栏和状态栏
大多数图形用户界面都会提供菜单栏和工具栏,以便用户对那些常用的功能进行快速访问。
Qt通过“动作(Action)”的概念简化了有关菜单和工具栏的编程。一个动作(action)是一个可以添加到任意数量的菜单和工具栏上的项。创建菜单和工具栏主要包括以下步骤:
1、创建并且设置动作;
2、创建菜单并且把动作添加到菜单上;
3、创建工具栏并且把动作添加到工具栏上。
这一小节,将为上一节创建的主窗口添加菜单栏、工具栏和状态栏。
更新的mainwindow.h源码如程序清单14.10所示。
程序清单14.10更新的mainwindow.h源码
1 /* mainwindow.h */
2 #ifndef MAINWINDOW_H
3 #define MAINWINDOW_H
4
5 #include <QMainWindow> /* 包含对QMainWindow的定义 */
6
7 class QAction;
8 class QMenu;
9 class QToolBar;
10 class QLabel;
11
12 class MainWindow : public QMainWindow /* 声明MainWindow为QMainWindow的子类*/
13 {
14 Q_OBJECT;
15 public:
16 MainWindow(void);
17 ~MainWindow(void);
18
19 private:
20 QMenu *fileMenu; /* 文件菜单 */
21 QMenu *helpMenu; /* 帮助菜单 */
22
23 QToolBar *fileToolBar; /* 工具栏 */
24
25 QAction *openAction; /* 打开动作 */
26 QAction *closeAction; /* 关闭动作 */
27 QAction *aboutAction; /* 关于动作 */
28
29 QLabel *statusLabel;
30 };
31
32 #endif
该头文件主要添加一些私有成员的声明,如第20到29行的私有成员变量。
对于这些私有变量,使用了它们的类前置声明(第7到10行)。这样就不用包含与这些类相关的头文件(如<QMenu>、<QLabel>等),可以使编译过程更快一些。
接下来主要看一下更新的mainwindow.cpp源码,具体实现如程序清单14.11所示。
程序清单14.11更新的mainwindow.cpp源代码
1 /* mainwindow.cpp */
2
3 #include <QtGui>
4 #include "mainwindow.h"
5
6 MainWindow::MainWindow(void)
7 {
8 openAction = new QAction(tr("&Open"), this); /* 创建打开动作 */
9 openAction->setStatusTip(tr("Open the file")); /* 设置状态提示 */
10
11 closeAction = new QAction(tr("&Close"), this); /* 创建关闭动作 */
12 closeAction->setStatusTip(tr("Close the file")); /* 设置状态提示 */
13
14 aboutAction = new QAction(tr("&About"), this); /* 创建关于动作 */
15 aboutAction->setStatusTip(tr("About")); /* 设置状态提示 */
16
17 fileMenu = menuBar()->addMenu(tr("&File")); /* 创建file菜单 */
18 fileMenu->addAction(openAction);
19 fileMenu->addAction(closeAction);
20
21 helpMenu = menuBar()->addMenu(tr("&Help")); /* 创建help菜单 */
22 helpMenu->addAction(aboutAction);
23
24 fileToolBar = addToolBar(tr("&File")); /* 创建File工具栏 */
25 fileToolBar->addAction(openAction); /* 添加打开动作到File工具栏*/
26 fileToolBar->addAction(closeAction); /* 添加关闭动作到工具栏 */
27 fileToolBar->addAction(aboutAction); /* 添加关于动作到工具栏 */
28
29 statusLabel = new QLabel;
30 statusLabel->setMinimumSize(statusLabel->sizeHint());
31 statusLabel->setAlignment(Qt::AlignHCenter); /* 设置居中 */
32
33 statusBar()->addWidget(statusLabel); /* 添加状态标签到状态栏 */
34 }
35
36 MainWindow::~MainWindow(void)
37 {
38 }
第8至15分别创建不同的项,在字符串周围的tr函数调用是把它们翻译成其他语言的标记。每个QObject对象以及包含有Q_OBJECT宏的子类中都有这个函数的声明。尽管应用程序并没有要翻译成其他语言的打算,但是在用户可见的字符串周围使用tr()是一个很不错的习惯。
在这些字符串中,使用了“&”来表示快捷键,用户可在支持快捷键的平台下通过按快捷键激活,如本例的按下Alt + O激活Open动作。
在Qt中,菜单都是QMenu的实例。QmainWindow::menuBar函数返回一个指向QMenuBar的指针,菜单栏会在第一次调用menuBar函数的时候就创建出来。第17至19行创建了file菜单后,把Open和Close动作添加进去。通过类似的方法创建help菜单。
创建工具栏与创建菜单的过程很相似,第24至27行创建了file工具栏,添加了Open、Close和About的动作。
状态栏位于主窗口的最下方,用于显示状态提示消息。QMainWindow::statusBar函数返回一个指向状态栏的指针,第一次调用statusBar函数的时候会创建状态栏。状态栏指示器是一些简单的QLabel。
main.cpp文件不用改变,重新调用qmake-qt4命令进行编译,然后执行查看效果,命令如下:
$ qmake-qt4 –project
$ qmake-qt4
$ make
PC上的运行效果如图14.38所示。

图14.38更新的mainwindow界面
1.1.2 事件
事件(event)是由窗口系统或者Qt自身产生的,用于响应所发生的各类事情。当用户按下或者松开键盘或者鼠标上的按键时,就会产生一个键盘或者鼠标事件。当用户改变窗口的大小的时候也会产生一个绘制窗口的事件。刚才谈到的事件都是对用户的操作做出响应而产生的,还有一些事件是系统独立产生的,如定时器事件。
由于有信号与槽的机制,一般不需要考虑事件,在发生某些重要的事情时,Qt窗口部件都会发射信号。但是当需要编写自定义的窗口部件,或者希望改变已经存在的Qt窗口部件的行为,事件就变得十分有用。
不应该把“事件”和“信号”这两个概念混淆。事件关注的是窗口部件本身的实现,而信号关注的是窗口部件的使用。例如,当使用QPushButton时,用户更多关注该窗口部件是否有被人点击使用,即对它的clicked信号更为关注。而很少关心发射该信号的底层鼠标或者键盘事件。除非是要自定义一个类似QPushButton的类(窗口部件本身),就需要编写一定的处理鼠标和键盘事件的代码。
所有组件的父类QWidget定义了很多事件处理函数,如keyPressEvent函数、keyReleaseEvent函数、muuseDoubleClickEvent函数、mouseMoveEvent函数、mousePressEvent函数和mouseRelease函数等。
下面通过自定义一个标签的子类,当用户点击鼠标、移动鼠标和释放鼠标后,在该窗口部件中显示鼠标当前的坐标。该实例由三个文件组成:main.cpp、coordinate_label.h和coordinate_label.cpp。
coordinate_label.h源码如程序清单14.12所示。
程序清单14.12 coordinate_label.h源码
1 /* coordinate_label.h */
2
3 #ifndef COORDINATE_LABEL_H
4 #define COORDINATE_LABEL_H
5
6 #include <QLabel>
7
8 class QMouseEvent;
9
10 class CoordinateLabel : public QLabel /* 自定义QLabel的子类 */
11 {
12 protected:
13void mousePressEvent(QMouseEvent *event); /* 定义鼠标按下事件 */
14void mouseMoveEvent(QMouseEvent *event); /* 定义鼠标移动事件 */
15void mouseReleaseEvent(QMouseEvent *event); /* 定义鼠标释放事件 */
16 };
17
18 #endif
第13至15行声明需要重定义的事件处理函数。具体代码实现在coordinate_label.cpp文件中,源码如程序清单14.13所示。
程序清单14.13 coordinate_label.cpp源码
1 /* coordinate_label.cpp */
2
3 #include <QMouseEvent>
4 #include "coordinate_label.h"
5
6 void CoordinateLabel::mousePressEvent(QMouseEvent *event)
7 {
8 this->setText(QString("Mouse Press at:[%1, %2]")
9 .arg(event->x())
10 .arg(event->y()));
11 }
12
13 void CoordinateLabel::mouseMoveEvent(QMouseEvent *event)
14 {
15 this->setText(QString("Mouse Move at:[%1, %2]")
16 .arg(event->x())
17 .arg(event->y()));
18 }
19
20 void CoordinateLabel::mouseReleaseEvent(QMouseEvent *event)
21 {
22 this->setText(QString("Mouse Release at:[%1, %2]")
23 .arg (event->x())
24 .arg(event->y()));
25 }
类QString的具体用法可以查阅帮助文档,在本例中,将自定义的QLabel的子类CoordinateLabel,设置其文本显示为当前鼠标事件的x轴与y轴。
main.cpp的源码如程序清单14.14所示。
程序清单14.14main.cpp源码
1 /* main.cpp */
2
3 #include <QApplication>
4 #include "coordinate_label.h"
5
6 int main(int argc, char *argv[])
7 {
8 QApplication app(argc, argv);
9 CoordinateLabel *myLabel = new CoordinateLabel;
10 myLabel->setWindowTitle("Mouse Event Demo"); /* 设置窗口标题 */
11 myLabel->resize(300,200); /* 设置自定义的窗口部件尺寸*/
12 myLabel->show();
13 return app.exec();
14 }
建立一个新目录为coordinate_label,在该目录下添加coordinate_label.h、coordinate_label.cpp和main.cpp文件,然后调用qmake-qt4命令进行编译,然后执行查看效果,命令如下:
$ qmake-qt4 –project
$ qmake-qt4
$ make
PC上的运行效果如图14.39所示。

图14.39 coordinateLabel界面

联系方式
致远电子 (ID: ZLG_zhiyuan )
还没关注致远电子?您将错过每日泛着油光的干货!您将错过一段颠覆洋品牌的历史!!有时候你想证明给一万个人看,到后来,你发现只得到了一个明白的人,那就够了。你是我们期待已久的粥粉么?我们的微信号:ZLG_zhiyuan。

---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:ZLG立功科技一致远电子,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ----------------------------------------------------------------------------------------------------------------------
|