让qt应用程序支持触摸
一.设备驱动
我的触摸屏是usb接口的
可以参考下这2篇文件
http://blog.csdn.net/paomadi/article/details/8754783 usb触摸屏
http://blog.csdn.net/paomadi/article/details/8309861 输入子系统
不是usb接口的或者自己想写多一个也可以(需要我的源码的请留邮箱说下,我贴一部分)
usb子系统部分关键在于urb的数据传递
input子系统部分关键在于事件的设置及上报
#define M //多点触摸点数
在初始化init或者probe方法中
input_dev=input_allocate_device();//分配初始化输入设备
//(最好构建一个对象结构体,包含input设备和usb设备,或其他设备,将各个子系统的设备捆绑到一个对象中去) set_bit(EV_KEY, input_dev->evbit); //设置事件类型标志位
set_bit(EV_ABS, input_dev->evbit); set_bit(BTN_TOUCH, input_dev->keybit); //设置按键类型标志 #if M
//多点的这么设置参数(我的屏只支持单点,so没亲测)
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,1920, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,1080, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
#else
//单点的参数设置
input_set_abs_params(input_dev, ABS_X, 0, 0x7FFF, 0, 0); //设置参数
input_set_abs_params(input_dev, ABS_Y, 0, 0x7FFF, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
#endif 在接收到数据之后上报事件给input子系统
#if M
//input_report_abs(touch->input, ABS_MT_TOUCH_MAJOR, 0);
for(i=0;i<M;i++){
input_report_abs(touchkit->input, ABS_MT_TRACKING_ID,0);
input_report_key(touchkit->input, BTN_TOUCH, touchkit->press);
input_report_abs(touchkit->input, ABS_MT_POSITION_X, touchkit->x);
input_report_abs(touchkit->input, ABS_MT_POSITION_Y, touchkit->y);
input_report_abs(touchkit->input, ABS_PRESSURE, touchkit->press);
input_mt_sync(touchkit->input);
}
#else
input_report_abs(input_dev, ABS_X, touchkit->x);
input_report_abs(input_dev, ABS_Y, touchkit->y);
input_report_key(input_dev, BTN_TOUCH,touchkit->press);
input_report_abs(input_dev, ABS_PRESSURE, touchkit->press);
#endif
input_sync(input_dev);
usb能匹配直接用hid子系统那是极好的
可以这样调试hid的设备
mkidr /tmp/debugfs
mount -t debugfs debugfs /tmp/debugfs
cd /tmp/debugfs
cd hid
cd 进对应的hid设备文件夹
cat event
其他的一些调试查看方法
ls -l /dev/input查看输入input设备
其中可以看到 lrwxrwxrwx 1 root root 6 Jan 1 2000 touchscreen0 -> event1
/dev/input/touchscreen0是链接文件,链接到对应的触摸屏event1设备
查看event1是否触摸设备
cd /sys/class/input
cd event1
cd device
cat name
或者
cat /proc/bus/input/devices
比较Handlers和Name
cat /dev/input/touchscreen|hexdump 点击触摸屏查看接收到的数据
二.tslib
升级工具
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install libtool
解压tslib
tar xzf tslib-1.4.tar.gz
cd tslib
生产configure文件
./autogen.sh
创建安装目录
mkdir tmp
配置生成makefile文件
echo "ac_cv_func_malloc_0_nonnull=yes" >arm-none-linux-gnueabi.cache
./configure --host=arm-none-linux-gnueabi --cache-file=arm-none-linux-gnueabi.cache --prefix=$(pwd)/tmp
编译tslib
make
安装tslib
make install
安装完成后生成4个目录
/bin 目录包含ts_calibrate ts_test ts_harvest ts_print ts_print_raw测试执行文件
/etc 目录包含ts.conf配置文件
/include 目录包含 tslib.h头文件
/lib 目录包含 pkgconfig目录和ts目录和*.so(libts.so等)动态链接库
检验文件是否用交叉工具链编译的
file ts_calibrate查看打印的信息
文件系统配置
将/bin目录的和/etc目录下的文件复制到目标板文件系统的同样目录下
/include和/lib目录复制到目标板文件系统的/usr目录下
配置ts.conf
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
配置环境变量
打开目标板文件系统/etc/profile文件
export LD_LIBRARY_PATH=/usr/lib/ --库文件目录
export TSLIB_ROOT=/usr/ --tslib库文件/头文件根目录
export TSLIB_TSDEVICE=/dev/input/touchscreen0 --触摸屏设备文件路径
export TSLIB_CALIBFILE=/etc/pointercal --校正文件路径 运行ts_calibrates会自动生成
export TSLIB_CONFFILE=/etc/ts.conf --配置文件路径
export TSLIB_CONSOLEDEVICE=none --
export TSLIB_FBDEVICE=/dev/fb0 --fb显示设备文件路径
export TSLIB_TSEVENTTYPE=INPUT --触摸事件类型 input子系统
export TSLIB_PLUGINDIR=/usr/lib/ts --
tslib测试
运行ts_calibrate
打印:
xres = 1920, yres = 1080
显示屏出现校正画面
点击方块(左上角)
打印:
Took 1 samples...
Top left : X = 752 Y = 1248
再次点击方块(右上角)
打印:
Took 2 samples...
Top right : X = 31938 Y = 1468
再次点击方块(右下角)
打印:
Took 2 samples...
Bot right : X = 31986 Y = 30926
再次点击方块(左下角)
打印:
Took 1 samples...
Bot left : X = 728 Y = 31278
再次点击方块(正中间)
打印:
Took 1 samples...
Center : X = 16387 Y = 16403
3.813721 0.058434 0.000070
3.860352 0.000071 0.032752
Calibration constants: 249936 3829 4 252992 4 2146 65536
校验完在/etc目录下生成/etc/pointercal
ts_calibrate可能会遇到一些问题
提示不是支持的触摸屏:查看TSLIB_TSDEVICE环境变量是否设置对
没点击方块就自动校正了:1.驱动BTN_TOUCH或者ABS_PRESSURE的值固化成1了(有上报按下事件没上报松开事件)
2.库文件放错位置
运行ts_test
点击Drag按钮 可以拖动小方块
点击Draw按钮 可以在屏幕上画线
点击的时候会打印:xxx:[x坐标] [y坐标] [按下1/松开0]
1345221722.121520: 1920 1074 1
1345221722.121520: 1920 1074 1
1345221722.354517: 1920 1078 0
1345221724.035519: 1851 838 1
1345221724.045521: 1849 835 1
1345221724.065520: 1845 829 1
1345221724.081520: 1840 823 1
1345221724.091521: 1834 816 1
1345221724.104521: 1828 810 1
1345221724.121520: 1821 803 1
1345221724.137518: 1814 797 1
1345221724.153520: 1807 790 1
三.qt everywhere 4.8.1编译
重新配置tslib
/configure --host=arm-none-linux-gnueabi --cache-file=arm-none-linux-gnueabi.cache --prefix=/usr/local/tslib
修改安装目录
make
make install
修改qt-everywhere-opensource-src-4.8.1/mkspecs/qws/【xxx】/qmake.conf文件
QMAKE_CC = arm-none-linux-gnueabi-gcc -lts
QMAKE_CXX = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK = arm-none-linux-gnueabi-g++ -lts
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++ -lts
QMAKE_INCDIR =/usr/local/tslib/include
QMAKE_LIBDIR =/usr/local/tslib/lib
配置qt
.configure 后面加上 -no-mouse-linuxtp -qt-mouse-tslib
在test的过程中打印
Mouse driver(qt) ......pc tslib
表示库安装成功并成功检测到
编译qt
make
make install
example里面选择应用程序(推荐qt-everywhere-opensource-src-4.8.1/examples/widgets/calculator)
拷贝到目标板文件系统里
ldd calculator 查看calculator需要调用的库
打印:
libts-0.0.so.0 => /usr/lib/libts-0.0.so.0 (0x2ac3f000)
libQtGui.so.4 => /usr/lib/libQtGui.so.4 (0x2ac49000)
libQtNetwork.so.4 => /usr/lib/libQtNetwork.so.4 (0x2b6ae000)
libQtCore.so.4 => /usr/lib/libQtCore.so.4 (0x2b7d6000)
libpthread.so.0 => /lib/libpthread.so.0 (0x2ab6a000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x2bb35000)
libm.so.6 => /lib/libm.so.6 (0x2ab8a000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2ab40000)
libc.so.6 => /lib/libc.so.6 (0x2bc07000)
libdl.so.2 => /lib/libdl.so.2 (0x2bd31000)
librt.so.1 => /lib/librt.so.1 (0x2ab10000)
/lib/ld-linux.so.3 (0x2aaea000)
看到libts-0.0.so.0说明tslib在qt中移植成功
ldd是个脚本,交叉工具链里面找
拷贝库文件到/usr/lib
在qt-everywhere-opensource-src-4.8.1/lib里面有la、prl、so和so.xxx文件
拷贝so和so.xxx文件就行
配置环境变量
打开目标板文件系统/etc/profile文件,添加以下
export LD_LIBRARY_PATH=/usr/lib/ ----库文件目录
export QWS_SIZE=1920x1080 ----分辨率
export QWS_MOUSE_PROTO="tslib:/dev/input/touchscreen0 mouseman:/dev/input/mouse0" ----"鼠标"类型
QWS_MOUSE_PROTO指定qt的鼠标,由【”】【第1个设备名字】【:】【设备文件路径】【空格】【第2个设备名字】【:】【设备文件路径】...【“】构成设备名字不区分大小写
设备名字可以是:(tslib、qnx、integrity、linuxtp、auto、intellimouse、microsoft、mousesystems、mouseman、linuxinput、usb、linuxis...)
该环境变量在qt源码qt-everywhere-opensource-src-4.8.1/src/gui/embedded/Qwindowsystem_qws.cpp的QWSServer::openMouse()函数中读取
QString mice=QString::fromLatin1(qgetenv("QWS_MOUSE_PROTO"))语句读入到mice,调试分析可以从这里入手
打印读取的环境变量:qDebug()<<mice,读取环境变量到mice后会判断mice中有多少个空格" ",也就是判断有多少个“鼠标”设备,个数作为后面for语句的循环因子,
for语句则调用QWSMouseHandler *handler=d->newMouseHandler(mouse.at(i))创建"鼠标"句柄,-->QMouseDriverFactory::create-->具体“鼠标”设备句柄的创建函数
QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString &device)
{
QString driver = key.toLower();
#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
if (driver == QLatin1String("qnx") || driver.isEmpty())
return new QQnxMouseHandler(key, device);
#endif
#if defined(Q_OS_INTEGRITY) && !defined(QT_NO_MOUSE_INTEGRITY)
if (driver == QLatin1String("integrity") || driver.isEmpty())
return new QIntMouseHandler(key, device);
#endif
#ifndef QT_NO_QWS_MOUSE_LINUXTP
if (driver == QLatin1String("linuxtp") || driver.isEmpty())
return new QWSLinuxTPMouseHandler(key, device);
#endif
#ifndef QT_NO_QWS_MOUSE_PC
if (driver == QLatin1String("auto")
|| driver == QLatin1String("intellimouse")
|| driver == QLatin1String("microsoft")
|| driver == QLatin1String("mousesystems")
|| driver == QLatin1String("mouseman")
|| driver.isEmpty()) {
return new QWSPcMouseHandler(key, device); //mice...
}
#endif
#ifndef QT_NO_QWS_MOUSE_TSLIB
if (driver == QLatin1String("tslib") || driver.isEmpty()) //tslib
return new QWSTslibMouseHandler(key, device);
#endif
# ifndef QT_NO_QWS_MOUSE_LINUXINPUT
if (driver == QLatin1String("linuxinput") || \
driver == QLatin1String("usb") || \
driver == QLatin1String("linuxis"))
return new QWSLinuxInputMouseHandler(device);
# endif
#ifndef QT_NO_QWS_MOUSE_QVFB
if (driver == QLatin1String("qvfbmouse") || driver == QLatin1String("qvfb"))
return new QVFbMouseHandler(key, device);
#endif #if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL)
#ifndef QT_NO_LIBRARY
if (QWSMouseHandlerFactoryInterface *factory = qobject_cast<QWSMouseHandlerFactoryInterface*>(loader()->instance(driver)))
return factory->create(driver, device);
#endif
#endif
return 0;
}
如果鼠标类型没指定(mouseman之类的),则默认会调用/dev/input/mice这样会使你的触摸有点漂移的感觉,其实读取mice的数据时候读出来的数据是绝对位移+相对位移...的值
所以会漂移,这个情况很多人都碰到过,指定到专用的鼠标例如mouseman:/dev/input/mouse0这样的话就没问题了。
mice的读方法可以查看内核的mousedev.c文件的mousedev_read方法,其中有一句
memcpy(data, client->ps2 + client->bufsiz - client->buffer, count);
接着
copy_to_user(buffer, data, count) //有时间的不烦试试研究下这个
还有一种情况会引起漂移现象,那就是你的环境变量没读取对,
也就是QWS_MOUSE_PROTO为空,所以最好添加qDebug()<<mice去调试一下,悲剧的是我就是碰到这种情况,即使用env查看是正确的也不一定说明你读取的环境变量是对的,你的应用程序
可能是在其他级别的用户或者在其他的bash环境下执行的,你的环境变量不一定对他起效.修改代码调试编译qt时候只需重新make一次,然后把前面说的库文件拷贝过去目标板就行了,
不费时间的
这里的QWS_MOUSE_PROTO的设置最好要写个shell脚本测试下是否插了鼠标,是否插了触摸屏根据判断的结果来不同的设置QWS_MOUSE_PROTO环境变量最好
查看你应用程序调用了那个input设备,使用lsof命令工具
lsof /dev/input/touchscreen0
打印:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
xxxx 1771 root 41r CHR 13,65 0t0 2326 /dev/input/event1
就是说xxxx打开了/dev/input/touchscreen0这个设备,这个设备是链接文件链接到/dev/input/event1
如果设备文件打开正确,但是触摸时候鼠标指针不动,运行一下ts_calibrate生成pointercal文件后再试试
这里可以添加下面shell脚本,在你打开qt应用程序前先判断是否校正过了,矫正过则执行qt程序,没校正过则校正一下
if [ ! -f "/etc/pointercal" ]; then
ts_calibrate
fi
让qt应用程序支持触摸的更多相关文章
- Owl Carousel – 支持触摸的 jQuery 响应式传送带插件
Owl Carousel 是一个 jQuery 插件,使我们能够迅速地创建响应式传送带滑块.这个插件是触摸友好的,能与几乎任何的 HTML 内容兼容使用.另外,强大的选项设置支持分页/滑动速度,启用/ ...
- AudioPlayer.js,一个响应式且支持触摸操作的jquery音频插件
AudioPlayer.js是一个响应式.支持触摸操作的HTML5 的音乐播放器.本文是对其官网的说用说明文档得翻译,博主第一次翻译外文.不到之处还请谅解.之处. JS文件地址:http://osva ...
- QT 4.7支持中文(QT4.7)(中文)(makeqpf)
QT 4.7支持中文(QT4.7)(中文)(makeqpf) 摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器 ...
- Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法
Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法 最近由于老师要求要在Ubuntu下QT上进程多线程服务器的开发,虽然只是单纯的调用qt的network模块,但是为了避免麻烦,我 ...
- WPF应用程序支持多国语言解决方案
原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...
- Qt应用程序中设置字体
Qt应用程序中设置字体 应用程序中经常需要设置字体,例如office软件或者是其他的编辑器软件等等.这里主要涉及到如下几个概念:字体,字号以及风格(例如:粗体,斜体,下划线等等).Qt里面也有对应的类 ...
- macOS上实现Qt应用程序做文件关联打开
一.背景介绍 用Qt开发的应用程序要实现文件关联,双击时用默认关联的程序打开文件,在Windows上这个功能非常容易实现.Windows应用程序在安装的时候可以在注册表中写入相关的键值对.打开文件的时 ...
- Fluxbox 添加Qt应用程序menu
/********************************************************************************* * Fluxbox 添加Qt应用程 ...
- WPF 程序无法触摸操作?我们一起来找原因和解决方法!
WPF 自诞生以来就带着微软先生的傲慢.微软说 WPF 支持触摸,于是 WPF 就真的支持触摸了.对,我说的是"支持触摸",那种摸上去能点能动的:偶尔还能带点儿多指的炫酷效果.但是 ...
随机推荐
- ajax异步请求实例
1. 问题分析 用户管理显示页面:usermanagement.tpl(也可以说是MVC中的V,即视图) 用户管理数据发送页面:usermanagement.php(也可以说是MVC中的M,即模型) ...
- APEC计划指引我们前进:云计算服务将上升
APEC纲领指引我们前进:云计算服务业必将兴起 这是APEC领导人的合影: 这次APEC会议通过了<北京纲领>和<亚太伙伴关系声明>,进一步明白了亚太地区经济合作的发展方向.目 ...
- SOLR搭建企业搜索平台
一. SOLR搭建企业搜索平台 运行环境: 运行容器:Tomcat6.0.20 Solr版本:apache-solr-1.4.0 分词器:mmseg4j-1.6.2 词库:sogou-dic ...
- java 一个函数EnumMap返回多个值
java 一个函数如何返回多个值 在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!! 网上这个问题的解决方法: 1.使用map返回值:这个方法问题是,你并不知道如何返回值 ...
- python算法之二分查找
说明:大部分代码是在网上找到的,好几个代码思路总结出来的 通常写算法,习惯用C语言写,显得思路清晰.可是假设一旦把思路确定下来,并且又不想打草稿.想高速写下来看看效果,还是python写的比較快.也看 ...
- HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others) Memory Limit: ...
- Qt之开机自启动
Windows开机自启动的程序很多,包括系统软件.杀毒软件.一些其他安装软件等等.当然可以禁止,通过软件管理或者手动删除对应的注册表中的项即可!但是为了系统的服务或者操作上的方便,我们往往需要开机自启 ...
- android布局margin和padding差异!
事实上从使用的时候就能够差别开来. android:padding android:layout_margin padding是在本控件级别的,而margin是在layout级别的. 最好拿有背景的控 ...
- 译文:前端性能的重要性 The Importance of Frontend Performance
欢迎訪问我的主页.最新的文章我会首先公布在个人主页上: http://blog.guaidm.com/shocky/ 原书下载地址:http://pan.baidu.com/s/1pJocRwB 在我 ...
- 内省(一)之Introspector、BeanInfo、PropertyDescriptor
内省(Introspector)是专门用来操作JavaBean属性的.不是所有的字段(Field)都能被称之为属性,只有某些字段具有getXXX或setXXX方法的才能称之为属性,当然要称为是一个Be ...