测试的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 #视情况而定