嵌入式linux解决QT应用程序不响应触摸屏的问题

来源:本站
导读:目前正在解读《嵌入式linux解决QT应用程序不响应触摸屏的问题》的相关信息,《嵌入式linux解决QT应用程序不响应触摸屏的问题》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《嵌入式linux解决QT应用程序不响应触摸屏的问题》的详细说明。
简介:这篇文章主要对于新手入门非常有所帮助。运用嵌入式linux解决QT应用程序不响应触摸屏的问题。希望对大家的学习有所帮助。

Qt的应用程序已经能够在am335x的linux3.2.0平台上运行,点击触摸屏也能够进行操作了。但是现在有一个小的bug,在运行qt应用程序前如果USB接口的触摸屏断开,或者运行中触摸屏断开,之后如果触摸屏设备又自动恢复,应用程序是不能自动恢复触摸屏的工作,只能退出应用程序然后再重新启动应用程序,才能继续使用触摸屏。这个bug对于工控机就是一个比较严重的问题,设备正在工作,不可能强行退出程序重新启动来恢复对触摸屏的响应,所以我们需要修改qt以及tslib的源程序,来增加自动检测触摸屏设备,并自动恢复应用程序对触摸屏的响应的功能。

通过分析qt5.4.1的源程序发现,qt gui中初始化触摸屏事件是使用的QTsLibMouseHandler这个类,在这个类的构造函数中:

m_dev =ts_open(device.constData(), 1);

if (!m_dev) {

qErrnoWarning(errno,"ts_open() failed.");

return ;

}

上面的代码我们可以分析出来,启动qt应用程序时如果不能正确打开tslib触摸屏,则会错误退出并继续运行qt应用程序,但是如果正确打开了tslib设备并正确设置参数后,会注册signal-slot以及notifier:

if(fd >= 0) {

m_notify = new QSocketNotifier(fd, QSocketNotifier::Read, this);

connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));

}else {

qWarning("Cannot open mouse input device '%s': %s",device.constData(), strerror(errno));

}

上述代码执行成功后,corelib会通过qeventdispatcherunix.cpp中的doSelect来检查注册的notifier以及调度signal-slot。对于工控的要求,这里的doSelect有一个小小的缺陷,就是当select返回错误时,doSelect将会禁止出错的notifier和signal-slot。这样,当触摸屏设备出现错误时,doSelect将会禁止QTsLibMouseHandler注册的notifier和signal-slot,即使后续触摸屏设备自动恢复了,qt也不能正常继续使用触摸屏,必须重新启动qt程序,重新执行上述的QTsLibMouseHandler构造函数,才能够继续使用触摸屏设备。

我做了两个大的修改,来解决这个问题:

A、修改tslib,增加一个ts_status函数,用来提供给用户程序获取USB触摸屏的设备状态,该函数返回-1表示USB触摸屏出现问题,不能读取数据。返回0表示USB触摸屏工作正常。

同时在tslib的插件中添加相应的读取状态的函数,顶层的ts_status是通过下一层的接口函数来获取设备信息,所以需要在每一层都增加相应的函数。

在tslib/src下添加一个ts_status.c的文件,添加ts_status函数(省事,我将这个函数增加到了ts_read.c中,没有增加ts_status.c文件,并需要在tslib.h中添加函数申明):

int ts_status(struct tsdev *ts)

{

int result;

result=ts->list->ops->stat(ts->list);

return result;

}

修改ts_filter.h,增加获取状态的函数到结构中:

struct tslib_ops {

int (*read)(structtslib_module_info *inf, struct ts_sample *samp, int nr);

int (*fini)(structtslib_module_info *inf);

int (*stat)(structtslib_module_info *inf);//增加获取状态的函数

};

修改tslib/plugins下的dejitter,input-raw,linear,pthres和variance,其中input-raw与触摸屏设备有关,我这里使用linux的usb设备,所以使用这个模块,其他四个是灵敏度,滤波等模块。

input-raw.c:

static int ts_input_stat(struct tslib_module_info *inf)

{

struct tslib_input *i =(struct tslib_input *)inf;

int ret=check_fd(i);

return ret;

}

static const struct tslib_ops __ts_input_ops = {

.read = ts_input_read,

.fini = ts_input_fini,

.stat = ts_input_stat,//增加函数

};

修改dejitter.c,linear.c,pthres.c和variance.c,添加相应的函数。这里只列出pthres的修改,其他三个模块的修改和pthres相同:

static int pthres_stat(struct tslib_module_info *info)

{

returninfo->next->ops->stat(info->next);

}

static const struct tslib_ops pthres_ops =

{

.read = pthres_read,

.fini = pthres_fini,

.stat = pthres_stat,

};

B、修改qt5.4.1的源程序,在QTsLibMouseHandler中添加一个守护进程,用来通过ts_status不断获取USB触摸屏的状态,当状态为不能读取数据时,注销注册的触摸屏事件管理器,并不断尝试重新打开触摸屏设备。

如果守护进程成功的重新打开了触摸屏设备,则重新注册触摸屏事件管理器。守护进程是一个1秒钟的定时器。

在QTsLibMouseHandler类中添加一个devTsLib变量,用于保存Tslib设备的信息。修改构造函数,增加下面红色的两行代码:

if (device.isEmpty())device = QByteArrayLiteral("/dev/input/event1");

devTslib=device;//保存设备信息

m_Timer=startTimer(1000);//增加一个1秒的定时器,用作守护进程

m_dev = ts_open(device.constData(), 1);

if (!m_dev) {

qErrnoWarning(errno, "ts_open() failed.");

return ;

}

然后实现守护进程:

void QTsLibMouseHandler::timerEvent(QTimerEvent *event)

{

if(m_dev){

if(ts_status(m_dev)==-1){

qDebug()<<"the tslib device was disconnect.";

ts_close(m_dev);

m_dev=0;

disconnect(m_notify, SIGNAL(activated(int)), this,SLOT(readMouseData()));

delete(m_notify);

}

} else {

qDebug()<<"re-open the tslib device.";

m_dev =ts_open(devTslib.constData(), 1);

if(m_dev){

ts_config(m_dev);

int fd =ts_fd(m_dev);

if (fd >= 0) {

m_notify = new QSocketNotifier(fd,QSocketNotifier::Read, this);

connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));

qDebug()<<"open the tslib device sucessful.";

} else {

qWarning("Cannot open mouse inputdevice '%s': %s", devTslib.constData(), strerror(errno));

}

} else {

qDebug()<<"could not open the tslib device.";

}

}

}

先重新编译tslib,并将编译后的tslib安装到需要的位置。

然后编译qt5.4.1的gui,并将编译后的libqt5gui相关的6个文件拷贝到需要的位置。

通过上述的修改源程序,解决了两个问题:

1、启动qt程序前,触摸屏设备没有准备好,导致的qt程序启动后,即使触摸屏设备正常了,qt程序也不能恢复使用触摸屏的问题。

2、qt程序启动后,能够正常使用触摸屏设备,但是由于触摸屏设备意外异常后,即使触摸屏设备自动恢复正常,qt程序也不能自动恢复使用触摸屏的问题。

现在,就完成了开发平台的基础搭建工作,一共做了以下的工作:

1、安装ubuntu14.04,并安装相应的软件,交叉编译工具,nfs和tftp服务;

2、在ti官网下载uboot,linux kernel,并配置交叉编译环境,进行正确编译,生成MLO、u-boot.img、uImage;

3、修改uboot,和kernel,尤其是kernel,支持定制am335x平台的各硬件;

4、下载tslib1.6.0,并交叉编译;

5、下载mkfs工具包,并编译生成mkfs.ubifs工具,用于制作ubi文件镜像;

6、下载qt5.4.1,并交叉编译,生成用于开发am335x平台qt程序的开发包;

7、修改tslib和qt5.4.1,用于支持特殊功能;

8、编写一个qt应用程序,交叉编译并正确运行于am335x上。

后续将进行的工作:

1、UART1将使用为RS485通信,修改omap-serail.c,增加一个GPIO,用于控制MAX487的数据发送和接收;

2、业余时间移植SGX Graphics_SDK_5010102到kernel3.2.0,实现图形加速和3D,准备自己开发一款3D游戏机;

提醒:《嵌入式linux解决QT应用程序不响应触摸屏的问题》最后刷新时间 2024-03-14 01:02:39,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《嵌入式linux解决QT应用程序不响应触摸屏的问题》该内容的真实性请自行鉴别。