找回密码
 立即注册
Qt开源社区 门户 查看内容

【Linux公开课】Qt编程实战!(中)

2019-2-9 10:15| 发布者: admin| 查看: 667| 评论: 0

摘要: 作者:ZLG致远电子 摘要由于Qt具有良好的可移植性,在桌面版本中编译运行成功的应用程序,一般只需要用交叉编译工具的qmake重新编译,即可在目标板上运行。执行嵌入式的qmake(别名qmake-arm),重新交叉编译,便可 ...
作者:ZLG致远电子





摘要

由于Qt具有良好的可移植性,在桌面版本中编译运行成功的应用程序,一般只需要用交叉编译工具的qmake重新编译,即可在目标板上运行。执行嵌入式的qmake(别名qmake-arm),重新交叉编译,便可获得嵌入式版本的Qt程序。

文员也能看懂学通的《嵌入式Linux开发教程》正式开始免费连载啦!致远电子微信公众平台【独家首发】。在这个教程中,你看不到自我陶醉的炫技,内容通俗易懂,实用够用为先。本教程凝聚了ZLG致远电子嵌入式工程师的心血,转载请【注明出处】。

1.1.1 信号与槽

信号与槽的机制是Qt编程的一个重要部分。这个机制可以在对象之间彼此并不了解的情况下,将它们的行为联系起来。它跟UNIX的信号不是同一个概念,不可相互混淆。

槽和普通的C++成员函数很像,它们可以是虚函数(virtual),也可被重载(overload),可以是公有的(public),保护的(protected),它们可以像任何c++成员函数一样被调用,可以传递任何类型的参数。不同在于一个槽函数能和一个信号相连接,只要信号发出了,这个槽函数就会自动被调用。信号和槽函数间的链接通过connect实现。Connect函数语法如下:


connect(sender, SIGNAL(signal), receiver, SLOT(slot));


sender和receive是QObject对象(QObject是所有Qt对象的基类)指针,signal和slot是不带参数的函数原型。SIGNAL宏和SLOT宏的作用是把它们转换成字符串。

虽然在之前的小节中,已经使用了信号和槽,但是在实际应用中还需要考虑一些规则:

1)一个信号可以连接到多个槽


connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));

connect(slider, SIGNAL(valueChanged(int)), this, SLOT(updateStatusBar(int)));


将滑块的值改变信号,连接微调框的设置值大小的槽和当前对象的更新状态栏的槽。

当信号发出后,槽函数都会被调用,但是调用的顺序不确定,随机的。

2)多个信号可以连接到一个槽


connect(lcd, SIGNAL(over()), this, SLOT(handleError());

connect(calculator, SIGNAL(divisionError()), this, SLOT(handleError()));


将lcd的over()信号和计算器的divisionError()信号与当前对象的handleError()的槽连接。

任何一个信号发出,槽函数都会被执行。

3)一个信号可以和另一个信号相连


connect(lineEdit, SIGNAL(textChanged(Qstring &)), this, SIGNAL(update(Qstring &)));


将文本框的文本改变信号与当前对象的更新信号相连。

第一个信号发出后,第二个信号也同时发送,除此之外,信号与信号连接上,和信号和槽连接相同。

4)连接可以被删除


disconnect(lcd, SIGNAL(over()), this, SLOT(handleError()));


这个函数很少使用,一个对象删除后,Qt自动删除与这个对象相关的所有连接。

注:信号和槽函数必须有着相同的参数类型,这样信号和槽函数才能成功连接。

如果信号里的参数个数多余槽函数的参数,多余的参数被忽略:


connect(ftp, SIGNAL(rawReply(int, const Qstring &)), this, SLOT(checkError(int)));


如果参数类型不匹配,或者信号和槽不存在,则当应用程序使用debug模式构建后,Qt会在运行期间发出警告。如果信号和槽连接时包含了参数的名字,Qt将会给出警告。

接下来,可以利用信号与槽将前面小节介绍的按钮部件提供退出功能,更新的quitButton.cpp源码如程序清单14.5所示。

程序清单14.5更新的quitButton.cpp源码


1 /* quitButton.cpp */

2 #include <QApplication>

3 #include <QPushButton>

4 int main(int argc, char *argv[])

5 {

6 QApplication app(argc, argv);

7 QPushButton *button = new QPushButton("Quit");

8 QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit()));

9 button->show();

10 return app.exec();

11 }


其实就只是增加了第7行代码,将这个按钮的clicked()信号与QApplication对象的quit()槽连接起来。

再介绍一个简单的示例,说明如何利用信号与槽的机制来同步窗口部件,可以通过操作微调框(spin box)或者滑块(slider)来完成数字输入,源码如程序清单14.6所示。

程序清单14.6number.cpp源码


1 /* number.cpp */

2 #include <QApplication>

3 #include <QHBoxLayout>

4 #include <QSlider>

5 #include <QSpinBox>

6

7 int main(int argc, char *argv[])

8 {

9 QApplication app(argc, argv);

10 QWidget *window = new QWidget;

11 window->setWindowTitle("Enter Number");

12

13 QSpinBox *spinBox = new QSpinBox; /* 创建微调框 */

14 QSlider *slider = new QSlider(Qt::Horizontal); /* 创建滑块 */

15 spinBox->setRange(0, 100); /* 设置微调框有效范围 */

16 slider->setRange(0, 100); /* 设置滑块有效范围 */

17

18 QObject::connect(spinBox, SIGNAL(valueChanged(int)),slider, SLOT(setValue(int)));

19 QObject::connect(slider, SIGNAL(valueChanged(int)),spinBox, SLOT(setValue(int)));

20 spinBox->setValue(25); /* 设置微调框的值为25 */

21

22 QHBoxLayout *layout = new QHBoxLayout; /* 创建水平布局管理器 */

23 layout->addWidget(spinBox); /* 从左到右放置部件 */

24 layout->addWidget(slider);

25 window->setLayout(layout);

26

27 window->show();

28

29 return app.exec();

30 }


第18至19行调用了两次QObject::connect函数,这是为了确保能够让微调框和滑块同步,以便它们两个总是可以显示相同的数值。只要有一个窗口部件的值改变了,就会发射它的valueChanged(int)信号,而另一个窗口部件就会用这个新值调用它的setValue(int)槽。

建立一个新目录为number,在该目录下添加number.cpp源代码文件,然后调用qmake命令进行编译,然后执行查看效果,命令如下:


$ qmake-qt4–project

$ qmake-qt4

$ make


本机执行过程如图14.35所示。



图14.35 number编译和执行过程

1.1.2 主窗口(MainWindow)

应用程序的主窗口提供了用于构建应用程序用户界面的框架,可以通过子类化QMainWindow创建。

一个主窗口主要由菜单栏,工具栏,状态栏、停靠窗口和中央窗口部件组成,如图14.36所示。



图14.36主窗口示意图

最上面是窗口标题栏,用于显示标题和一些按钮,如最小化、最大化、关闭按钮等。接下来是菜单栏,显示菜单,然后是工具栏,用于显示工具条,由于Qt的窗口支持多个工具条的显示,所以你可以在四周显示或者并排显示工具条。工具条的下面是停靠窗口,所谓停靠窗口就像画图的工具箱一样,可以在中央窗口的四周显示。再下来是状态栏,显示一些状态,比如鼠标当前位置等。中间最大的中央窗口部件是主要的工作区。

一个最基本的主窗口可以由以下三个文件组成:main.cpp、mainwindow.h和mainwindow.cpp。

mainwindow.h的源码如程序清单14.7所示。

程序清单14.7mainwindow.h源代码


1 /* mainwindow.h */

2 #ifndef MAINWINDOW_H

3 #define MAINWINDOW_H

4

5 #include <QMainWindow> /* 包含对QMainWindow的定义 */

6

7 class MainWindow : public QMainWindow /* 声明MainWindow为QMainWindow的子类*/

8 {

9 Q_OBJECT;

10 public:

11 MainWindow(void);

12 ~MainWindow(void);

13 };

14

15 #endif


第2和3行能够防止对该头文件的多重包含。

第9行对于所有定义了信号和槽的类,在类定义开始处的Q_OBJECT宏是必需的。

第11和12行声明类MainWindow的构造函数和析构函数。

接下来看一下mainwindow.cpp对类MainWindow的实现,源码如程序清单14.8所示。

程序清单14.8mainwindow.cpp源码


1 /* mainwindow.cpp */

2

3 #include "mainwindow.h" /* 包含mainwindow.h头文件 */

4

5 MainWindow::MainWindow(void)

6 {

7 }

8

9 MainWindow::~MainWindow(void)

10 {

11 }


由于只是创建一个基本的主窗口,不包含其他窗口部件,所以,构造函数和析构函数都没有内容。下一小节将会在里面添加构造菜单栏和工具栏的实现。

最后,看一下main.cpp文件,源码如程序清单14.9所示。

程序清单14.9main.cpp源码

1/* main.cpp */

2

3#include <QApplication>

4#include "mainwindow.h"

5

6int main(int argc, char *argv[])

7{

8QApplication app(argc, argv);

9MainWindow main;/* 创建自定义的MainWindow对象 */

10main.show();/* 使对象显示 */

11return app.exec();

12 }

这就是一个最基本的主窗口的所需要的文件。

建立一个新目录为mainwindow,在该目录下添加mainwindow.h、mainwindow.cpp和main.cpp文件,然后调用qmake-qt4命令进行编译,然后执行查看效果,命令如下:


$ qmake-qt4 –project

$ qmake-qt4

$ make


PC上的运行效果如图14.37所示。



图14.37 mainwindow运行界面






联系方式


  • 销售电话:400-888-4005拨1

  • 技术支持电话:400-888-4005拨2

  • 邮箱:zydz@zlg.cn

  • 官方网页:http://www.zlg.cn


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





-------------------------------------------------------------------------
我们尊重原创,也注重分享,如若侵权请联系qter@qter.org。
-------------------------------------------------------------------------

鲜花

握手

雷人

路过

鸡蛋

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了