一、QT背景知识介绍

1、常见GUI系统

(1)Labview、Mac、Windows等
(2)GNOME(底层还是GTK图形界面库)、KDE(QT库)
(3)QT(适合不追求界面美观,只追求界面比较稳定,如工业领域)
(4)miniGUI、uCGUI(stemWin):主要单片机在用,例如stm32

2、QT的发展例程

(1)1991年由TrollTech(奇趣科技)开发

(2)2008年被Nokia收购,改名为QT Software,后又改为Qt Development Frameworks,引入QTCreator作为IDE。给开发者提供QT SDK(QT SDK = QT Framework + QTCreator)

(3)2012年被Digia收购并运营至今。

(4)2014.4发布QtCreator3.1.0,全面支持iOS、Android、WP(windows phone),做到真正的跨平台。

3、QT如何跨平台

(1)QT主体使用C++编写,应用开发也使用C++。

(2)QT跨平台的原理是:一次编写、到处编译(需安装支持不同系统的库)并运行,源码跨平台。(注意和Java的差别,java是可执行程序级别的,一个编译好的程序各个平台都可以运行)

(3)QT支持的平台:Windows(32/64),X11(linux/Unix)、Mac(MacOSX)、Embeded(linux fb)、Android/ioS/WP

4、QT相关的其他一些名字

(1)Qt/E,QT embeded,名称三次变更:QT/E -> Qtopia-core -> Qt-embedded-opensource,Qt4.5后大一统为:qt-everywhere-opensource-src

(2)Qtopia,SourceForge.net上的开源项目,全称Qt Palmtop Environment,基于QtE,为掌上电脑PDA等开发的专属桌面环境,已停止开发并入QT主线。

5、QT的网络资源

(1)QT官网:https://www.qt.io/
在这里插入图片描述
(2)QT源码及各种资源的下载主站:http://download.qt.io/archive/qt/
在这里插入图片描述

二、QT的官网资源开发环境搭建

1、QT官网资源

(1)主流版本:QT4.8、QT5.x
  较高版本的QT支持的C++版本较高,而x210开发板的交叉编译链是2009年的,支持的C++版本较低,支持C++98,QT5.9支持的最少也是C++11,故而选择QT5.6。

2、QT开发环境搭建

(1)Windows下本地开发环境,安装相应的软件
在这里插入图片描述
(2)Linux(Ubuntu)下本地开发
(3)Linux(Ubuntu)下交叉编译环境
具体安装步骤可自行百度,参考别人提供的方法,这里不再赘述!

3、QT的linuxfb介绍

参考阅读:
https://blog.csdn.net/wuu19/article/details/100097366
https://blog.csdn.net/weixin_45842280/article/details/120572842
https://blog.csdn.net/deggfg/article/details/81478056

linuxfb与framebuffer驱动有关,即其与控制屏幕画面的显示有关。

(1)XWindow(XServer + XClient)
参考学习:https://blog.csdn.net/qq_22059611/article/details/88027265

(2)QT4中的QWS (程序在命令行执行时的操作方法:./app -qws)

(3)QT5中QPA(无窗口系统:linuxfb/eglfs 简单窗口系统:Wayland)

补充了解:
mingw:minst gcc for windows,在Windows中运行的gcc编译器,如果想把linux中的软
件移植到windows中就可以借助mingw。
x64:64X86:32

三、移植前的准备和确认工作

1、移植环境

(1)Windows10 64位+ Ubuntu16.04 X64,共享文件夹winshare(在ubuntu中的目录为:/mnt/hgfs/winshare)

(2)开发板内核:linux2.6.35.7,支持nfs启动、fb(framebuffer)驱动与ts(触摸屏)驱动均正常工作

(3)移植QT版本:QT5.6.2

2、开发板状况确认

(1)已经烧录uboot,并设置环境变量bootcmd和bootargs从tftp、nfs启动

(2)zImage事先编译好的,文件夹形式的rootfs准备好,成功启动内核进入命令行。

(3)ts驱动源码确认添加、设备文件确认ok(/dev/input/event?)

3、测试确认ts驱动部分

(1)cat /proc/bus/input/devices 可知gslX680对应的设备文件是event2
打印的信息:

I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="gslX680"
P: Phys=
S: Sysfs=/devices/platform/s3c2440-i2c.1/i2c-1/1-0040/input/input2
U: Uniq=
H: Handlers=mouse1 event2 
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=1000003

(2)cat /dev/input/event2
  触摸开发板屏幕,看开发板系统终端命令行是否会打印信息,若打印则证明该触摸屏驱动可正常工作

(3)也可通过写应用程序,使用API来测试

int main(int argc, char *argv[])
{
	int fd = -1, ret = -1;
	struct input_event dev;
	
	//第一步:打开设备文件
	fd = open(DEVICE_TOUCHSCREEN, O_RDONLY);
	if (fd < 0)
	{
		perror("open failure.");
		return -1;
	}

	while(1)
	{
		//第二步:读取一个event事件包	
		memset(&dev, 0, sizeof(struct input_event));
		ret = read(fd, &dev, sizeof(struct input_event));
		if (ret != sizeof(struct input_event))
		{
			perror("read failure.");
			break;
		}
		
		//第三步:解析event包,知晓发生了什么样的输入事件
		printf("------------------------------------\n");
		printf("type:%d\n", dev.type);
		printf("code:%d\n", dev.code);
		printf("value:%d\n", dev.value);
		printf("\n");
	}
	return 0;
}

四、tslib移植和测试

  Tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口。tslib在各种硬件体系结构和操作系统上运行

1、tslib移植

(1)源码下载
链接:https://pan.baidu.com/s/1jhkgr5rkaP7zn3z3b8cZQQ 
提取码:2wt3 
--来自百度网盘超级会员V5的分享
(2)解压		tar -xvf tslib-1.4.tar.gz
(3)配置
cd tslib
./autogen.sh  #检查环境是否完整、可用
echo "ac_cv_func_malloc_0_nonnull=yes">arm-linux.cache 
mkdir /opt/tslib  #创建一个安装目录,将编译好的tslib放在这个目录
./configure --prefix=/opt/tslib --host=arm-linux --cache-file=arm-linux.cache
(4)编译和安装
make
make install

2、问题及解决:

  如果./autogen.sh时报错:./autogen.sh: 4: autoreconf: not found,是因为系统中没有安装autoconf工具.
  解决方法:先让ubuntu能上网,然后执行:

sudo apt-get install autoconf automake libtool

3、部署

(1)动态库文件so

mkdir /home/rootfs/usr/lib -p #开发板nfs方式的根文件系统所在目录/home/rootfs/
cp *so* /home/rootfs/usr/lib -rf

(2)修改(运行时)配置文件
/opt/tslib/etc/ts.conf,其中的配置项会影响tslib的运行。修改这个配置文件:

# Uncomment if you wish to use the linux input layer event interface
module_raw input//将这条语句放出来,不被隐去,负责执行测试程序会报错,无法找到模型

(3)bin目录文件

可一步到位将tslib整个文件夹复制到/home/rootfs/,然后去导出环境变量,tslib目录
下的include目录可删掉,因为该目录里的头文件在编译时有用,运行时用不到。tslib/lib
下的libts.la也可删掉,其是静态链接库,编译时用到,运行时不需要。

4、导出环境变量

定义tslib运行需要的环境变量

export TSLIB_TSDEVICE=/dev/input/event2#触摸屏设备的驱动文件,不同开发板的目录有所区别

export TSLIB_CALIBFILE=/tslib14/etc/pointercal#这个目录/tslib14/etc改成与自己开发板相符的,可将
tslib文件夹名称修改为tslib14,pointercal校准时生成的校准文件

export TSLIB_CONFFILE=/tslib1.4/etc/ts.conf#配置文件

export TSLIB_PLUGINDIR=/tslib1.4/lib/ts#插件

export TSLIB_CONSOLEDEVICE=none#不要控制台

export TSLIB_FBDEVICE=/dev/fb0#确认一下自己的开发板framebuffer是不是fb0

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tslib1.4/lib#共享库

export TS_INFO_FILE=/sys/class/input/input2/uevent#自动安装驱动相关的

export是动态导出,每次开机都要导出一次,所以把这些命令添加到/etc/profile文件中开机自动运行,然后重启开发板。

5、运行和测试

tslib1.4中提供了测试程序如ts_test
(1)错误1:No raw modules loaded.
ts_config: No such file or directory

解决:在etc/ts.conf中打开module raw input这行的注释就行了。

(2)错误2:"selected device is not a touchscreen I understand"问题解决

可参考:https://www.cnblogs.com/053179hu/p/13866983.html
内核中EV_VERSION的值:#define EV_VERSION 0x010001

接着查看tslib库中使用的EV_VERSION宏的值,该宏值存放在编译器的目录中的input.h文件中 ,即在交叉编译链中的:
/usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/usr/include/linux/
input.h:32:#define EV_VERSION 0x010000

将二者修改成一样即可解决问题。

./ts_calibrate执行后打印出的常量保存在/etc/pointercal,屏幕的校准参数。电容屏不做这一步也可以,也是准的。但用了tslib还是校准一下

五、QT5.6.2配置和交叉编译

1、源码下载和解压

(1)源码下载目录:自行放置到ubuntu中的一个目录即可
(2)创建工作目录,并解压
(3)创建安装目录 :/opt/QT5.6.2

2、配置

在这里插入图片描述
(1)配置相应的qmake(提供很多个配置好的例子,选择一个类似的适合自己的去修改:linux-arm-gnueabi-g++),修改qtbase/mkspecs/linux-arm-gnueabi-g++/qmake.conf文件

#添加以下内容
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS_RELEASE   += -O2  -march=armv7-a    #根据芯片改正-march=  -O2是编译器的优化等级   
QMAKE_CXXFLAGS_RELEASE += -O2  -march=armv7-a

# modifications to g++.conf
QMAKE_CC = arm-linux-gcc -lts
QMAKE_CXX = arm-linux-g++ -lts
QMAKE_LINK = arm-linux-g++ -lts
QMAKE_LINK_SHLIB = arm-linux-g++ -lts

# modifications to linux.conf
QMAKE_AR = arm-linux-ar cqs 
QMAKE_OBJCOPY = arm-linux-objcopy 
QMAKE_NM = arm-linux-nm -P
QMAKE_STRIP = arm-linuxi-strip 

修改后如下图所示:
在这里插入图片描述
在这里插入图片描述
(2)编译前配置(可以参考./configure --help的提示来配置,没有直接提供makefile,由./config得到makefile)

./configure :命令
-prefix:配置安装路径
'\' :连行符,续行符,要删空其后的空格,不然会出问题
-opensource:一种模式
-shared:配置成共享库
-c++std c++98:在整个编译过程中使用的C++标准,要和交叉编译链支持的c++标准相符合
linux-arm-gnueabi-g++:上面(1)所用的那个目录名
-qt-zlib、-qt-libjpeg:包含一些库,QT使用的
-no-sse2:-no不要的意思,-sse2库名
-I:编译时找的头文件的目录
-L:导出tslib的共享库,必须与之前移植tslib库的目录一致。
./configure  -prefix /opt/QT5.6.2  \
  -opensource  \
  -confirm-license \
  -release  \
  -shared  \
  -accessibility \
-c++std c++98 \
  -xplatform linux-arm-gnueabi-g++ \
-qpa linuxfb \
-linuxfb \
-qreal float \
-pch \
-qt-zlib \
  -qt-libjpeg \
          -qt-libpng \
-no-sse2 \
          -no-largefile \
          -no-qml-debug \
          -no-glib \
-no-gtkstyle \
  -no-opengl \
  -nomake tools \
  -nomake examples \
  -tslib \
  -skip qt3d -skip qtcanvas3d -skip qtdoc -skip qtwayland \
  -I /opt/tslib/include \
  -L /opt/tslib/lib

3、编译中的错误解决

(1)找不到dlopen(动态的打开动态链接库)或者dlsym(动态的去动态链接库加载某一个符号)。在上述qmake.conf文件中的arm-linux-g++未添加-ldl选项不会去链接dl库,在编译器后面加ldl即: arm-linux-g++ -ldl

(2)undefined reference t o `__sync_add_and_fetch_4’
参考http://www.mamicode.com/info-detail-1699895.html

  apt-get install libtool
  libtool --tag=CC --mode=compile arm-linux-gcc -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.c 
  
  libtool --tag=CC --mode=link arm-linux-g++ -g -O2 -o liblinux-atomic.la linux-atomic.lo

  利用libtool生成liblinux-atomic.a,注意生成的目录名叫.libs所以是隐藏的
  
  cp .libs/liblinux-atomic.a /opt/linux-automic	#注意/opt/linux-automic是自己事先创建的的一个文件夹

  再去QT源码下修改:./qtscript/src/script/Makefile
  在LIBS  = 的结尾添加 -L/opt/linux-automic -llinux-atomic
  /opt/linux-atomic 

4、编译,下载

make
make install

六、linux下QT应用开发环境搭建

QT Creator 只是一个集成的编译器,用于将源代码编译成可执行程序。QT是跨平台C++图形用户界面应用程序开发框架,可以简单理解成是一个开发包。

1、ubuntu中本地QT开发环境搭建

(1)开发环境 = IDE(qtcreator) + QT库 = QT SDK

qt包下载地址:https://download.qt.io/new_archive/qt/
我们下载5.3.2版本进行开发,放在ubuntu中的某个目录进行安装,运行该安装包。
在这里插入图片描述
运行后会弹出一个图形界面来:
在这里插入图片描述
一直点击next即可,与windows下安装程序操作一样。安装完成后需要对该软件进行配置。进入到安装该软件的目录:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、ubuntu中QT交叉编译环境搭建

QtCreator中可以安装多个版本的qmake,每个qmake都可以单独使用来对同一套源码进行编译。我们只需要在安装好的本地qt sdk中手动添加上自己交叉编译的qt库的qmake,即可使用本地开发的qt sdk来进行交叉编译开发。

运行qtcreator:
在这里插入图片描述
在这里插入图片描述
创建一个程序,进行简单开发(可自行百多找个教程),然后编译,回头将编译好的程序复制到开发板目录执行测试。修改编译程序使用的编译链:
在这里插入图片描述
先去添加Compliers,再去修改Qt Versions(add qmake,我们交叉编译5.6.2生成的那个):
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
若遇到其他问题请自行百度解决或者购买朱老师的这个小项目课程学习(视频讲解操作是很详细的),因为有可能你遇到的问题我没有遇到。

在这里插入图片描述
在这里插入图片描述

七、在开发板中运行QT应用实验

1、rootfs中部署QT库

(1)QT库复制
将《 五》 中在ubuntu交叉编译生成的QT库移植到开发板的根文件系统上

mkdir /home/rootfs/QT5.6.2
cp /opt/QT5.6.2/lib /home/rootfs/QT5.6.2 -rf
cp /opt/QT5.6.2/plugins/ /home/rootfs/QT5.6.2/ -rf

(2)导出环境变量

export LD_LIBRARY_PATH=/QT5.6.2/lib:$LD_LIBRARY_PATH
export QT_QPA_PLATFORM_PLUGIN_PATH=/QT5.6.2/plugins   
export QT_QPA_FONTDIR=/QT5.6.2/lib/fonts            
export QT_QPA_FB_TSLIB=1    
export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event2          
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:size=1024x600:mmSize=1024x600:offset=0x0:tty=/dev/tty1

添加到/etc/profile,重启开发板

2、开发板中运行QT应用

(1)拷贝和执行

./可执行程序名

(2)问题解决和现象观察(若是遇到了某个问题我没有给出解决方法,说明我在移植过程中并未遇到,请自行解决)

问题1:找不到libQtxx			
解决:部署QT库等文件并导出环境变量
问题2:error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
解决:C++库在交叉编译工具链中,复制进去即可。在交叉编译链所在目录搜索找到它:

find -name "libstdc++*"

cp libstdc++*so* /home/rootfs/lib/ -rf
问题3:QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open
failed
QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open
failed

解决:缺少一个运行时库preloadable_libiconv.so,交叉编译得到这个后放进去/lib目录下即可。
参考:http://blog.csdn.net/wangyuanfei555/article/details/47399771
 下载:http://ftp.gnu.org/gnu/libiconv/libiconv-1.14.tar.gz  
(错误的,不过先按这个操作)./configure -prefix=$PWD/_install -host=arm-linux-gnueabihf  
				make  
                make install
                把_install/lib 下的preloadable_libiconv.so 拷到系统的/lib 下,  
                export LD_PRELOAD=/lib/preloadable_libiconv.so



	移植libiconv中遇到的问题及解决:
	1、./stdio.h:1010:1: error: ‘gets’ undeclared here (not in a function)
	_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
	
	解决:找到那一行,注释掉。
	 find -name "stdio.h"
	 vi ./srclib/stdio.h

	2、编译好的库是intel80386架构的,不是ARM的,不能用,要交叉编译才行。
	解决:先看配置好的Makefile,找交叉编译工具链的全局变量。但是本项目的Makefile中没有CC等这些定义,像这种一般就是通过环境变量来设置的。

	交叉编译libiconv,参考:http://blog.csdn.net/wuyu92877/article/details/52472810
	编译libiconv错误提示gets相关的,参考:http://blog.csdn.net/ownfire/article/details/47276219

	./configure -prefix=$PWD/_install --host=arm-none-linux-gnueabi
	make CROSS_COMPILE=arm-linux-none-gnueabi- ARCH=arm
	make install

	把_install/lib 下的preloadable_libiconv.so 拷到开发板的/lib 下,
	开发板的操作:export LD_PRELOAD=/lib/preloadable_libiconv.so
	添加到/etc/profile

注:本资料大部分由朱老师物联网大讲堂课程笔记整理而来并且引用了部分他人博客的内容,如有侵权,联系删除!水平有限,如有错误,欢迎各位在评论区交流。

Logo

更多推荐