Qt5触摸屏支持热插拔

测试的Qt5版本:5.12.8 ,5.9.1
基于Linuxfb和Tslib的触摸交互,当触摸屏热插拔后触摸无法恢复,需要修改Qt的tslib插件库源码。


QT支持热插拔的前提是Linux内核需要支持热插拔,event设备可以即插即用

源码路径:

qtbase/src/platformsupport/input/tslib/qtslib.cpp

static QString mKey;
static QString mSpecification;
static QByteArray mDevice;

QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
                                       const QString &specification,
                                       QObject *parent)
: QObject(parent),
m_notify(0), m_x(0), m_y(0), m_pressed(0), m_rawMode(false)
{
    qCDebug(qLcTsLib) << "Initializing tslib plugin" << key << specification;
    setObjectName(QLatin1String("TSLib Mouse Handler"));

    mKey=key;
    mSpecification=specification;

    QByteArray device = qgetenv("TSLIB_TSDEVICE");

    if (specification.startsWith(QLatin1String("/dev/")))
    device = specification.toLocal8Bit();

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

    m_dev = ts_open(device.constData(), 1);
    if (!m_dev) {
        qErrnoWarning(errno, "ts_open() failed");
        return;
    }

    if (ts_config(m_dev))
    qErrnoWarning(errno, "ts_config() failed");

    m_rawMode = !key.compare(QLatin1String("TslibRaw"), Qt::CaseInsensitive);

    int fd = ts_fd(m_dev);
    if (fd >= 0) {
        qCDebug(qLcTsLib) << "tslib device is" << device;
        m_notify = new QSocketNotifier(fd, QSocketNotifier::Read, this);
        connect(m_notify, &QSocketNotifier::activated, this, &QTsLibMouseHandler::readMouseData);
    } else {
        qErrnoWarning(errno, "tslib: Cannot open input device %s", device.constData());
    }
    
    mDevice=device;
    printf("mKey=%s  mSpecification=%s m_rawMode=%d mDevice=%s\n",mKey.toLatin1().constData(), mSpecification.toLatin1().constData(),m_rawMode,mDevice.constData());
}

void QTsLibMouseHandler::readMouseData()
{   
    ts_sample sample;
    bool ret;

      //ret = get_sample(m_dev,&sample,m_rawMode);
      //printf("get_sample_ret=%d\n",ret);
    while(get_sample(m_dev, &sample, m_rawMode)) {
//    if(ret {
        bool pressed = sample.pressure;
        int x = sample.x;
        int y = sample.y;

        // coordinates on release events can contain arbitrary values, just ignore them
        if (sample.pressure == 0) {
            x = m_x;
            y = m_y;
        }

        if (!m_rawMode) {
            //filtering: ignore movements of 2 pixels or less
            int dx = x - m_x;                
            int dy = y - m_y;
            if (dx*dx <= 4 && dy*dy <= 4 && pressed == m_pressed)
            continue;
        }
        QPoint pos(x, y);

        QWindowSystemInterface::handleMouseEvent(nullptr, pos, pos,
                                                 pressed ? Qt::LeftButton : Qt::NoButton,
                                                 Qt::NoButton, QEvent::None);

        m_x = x;
        m_y = y;
        m_pressed = pressed;
    }

//    printf("QtTslib readMouseData End\n");
#if 1
    if(access(mDevice.constData(),F_OK))
    {
        ts_close(m_dev);
        disconnect(m_notify);
        delete m_notify;

        while(1){
            printf("Please Input TouchScreen Device...\n");
            sleep(1);

            m_dev = ts_open(mDevice.constData(), 1);
            if (!m_dev) {
                continue;
            }

            if (ts_config(m_dev)){
                printf("QtLib: ts_config failed!\n");
            }

            m_rawMode = !mKey.compare(QLatin1String("TslibRaw"), Qt::CaseInsensitive);

            int fd = ts_fd(m_dev);
            if (fd >= 0) {
                qCDebug(qLcTsLib) << "tslib device is" <<mDevice;
                m_notify = new QSocketNotifier(fd, QSocketNotifier::Read, this);
                connect(m_notify, &QSocketNotifier::activated, this, &QTsLibMouseHandler::readMouseData);
                break;
            } else {
                qErrnoWarning(errno, "tslib: Cannot open input device %s", mDevice.constData());
            }

        }
    }
#endif 
}

将编译好的qtbase/plugins/platforms/libqlinuxfb.so安装到目标系统里

QT5.12.8环境变量

export QT_ROOT=/usr/lib
export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins 
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
export QT_QPA_FONTDIR=$QT_ROOT/fonts 
export QT_QPA_GENERIC_PLUGINS=Tslib:/dev/input/touchscreen0 
export QT_QPA_EVDEV_KEYBOARD_PARAMETERS=/dev/input/event0
export QML_IMPORT_PATH=$QT_ROOT/qml
export QML2_IMPORT_PATH=$QT_ROOT/qml
export QT_QPA_FB_TSLIB=1


export TSLIB_TSDEVICE=/dev/input/touchscreen0
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=/usr/lib/ts
export TSLIB_FBDEVICE=/dev/fb0
# export TSLIB_CONSOLEDEVICE=none #视情况而定
### Qt 应用中 USB 触摸屏重新连接问题及解决方案 #### 一、背景介绍 当USB触摸屏从计算机断开再重新连接时,可能会遇到Qt应用程序无法识别新的触摸输入或原有触摸功能失效的问题。这类情况不仅影响用户体验还可能造成数据录入错误等问题。 #### 二、原因分析 该类问题的发生通常源于操作系统未能及时更新其内部关于外设状态的信息或是图形界面框架本身对于硬件变化感知机制存在缺陷。具体到Qt环境下,早期版本可能存在对某些型号USB触摸设备的支持不够完善之处[^1];另外,环境因素如电子干扰也可能间接引发此类故障[^3]。 #### 三、解决办法 ##### 修改源代码适应不同版本需求 针对Qt5.x系列版本,可以通过修改`qtbase/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp`以及对应的头文件`.h`来增强系统对外部设备变更事件的捕捉能力,从而实现更稳定可靠的热插拔支持: ```cpp // qdevicediscovery_static.cpp 中适当位置增加如下逻辑判断语句 if (deviceIsTouchScreen(deviceInfo)) { // 对于检测到的新接入触摸屏执行初始化设置... } ``` ##### 调整配置参数优化性能表现 确保项目构建选项里包含了必要的平台特性开关,比如启用多点触控等功能模块。同时检查是否存在其他潜在冲突项需要关闭或调整优先级以获得最佳兼容效果。 ##### 排查外部干扰源减少误报几率 按照建议的操作指南尝试改变工作场所的位置或将受影响装置远离强磁场区域测试是否有改善迹象。这一步骤有助于区分问题是由于物理层面的原因引起还是纯粹软件方面造成的。 ##### 更新驱动程序保持最新状态 定期访问制造商官方网站下载安装最新的固件补丁包,确保所使用的硬件处于最优运行条件下能够最大程度发挥应有的效能并降低发生意外的概率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值