0

我们有一个 Qt GUI 应用程序在启动时通过注册表 Run/RunOnce-Key 启动。

当启动时,Qt 应用程序从触摸屏获取位置,但不获取单击事件(模拟鼠标单击按钮)本身。

手动运行时,Qt 应用程序获取位置并从触摸屏单击。

使用鼠标时,两个版本都可以正常工作。启动时启动的其他应用程序确实接受通过触摸单击。

我们没有实现任何 TouchEvents,触摸屏只是被解释为鼠标事件。我猜该应用程序只是为了快速并在触摸屏驱动程序完全加载之前启动,然后以某种方式错误地触发“点击”事件。但我根本不知道如何验证这一点或如何寻找问题。

我们运行不同的系统,没有出现这个问题,它只是我们现在遇到问题的这台 Windows 电脑。更换电脑是消除问题的一种选择,但我仍然想找到问题的根源,以确保不会再次发生这种情况。目前,100 个系统中就有一个存在此问题。

我编写了一个小的附加应用程序,将 eventFilter 安装到 qApp 以查看实际到达的事件。在启动时运行时,我只收到鼠标移动事件,而稍后手动启动时,我收到移动新闻稿事件。

我想知道其他人是否遇到过与 Qt/"clickapplications" 和触摸屏本身类似的触摸问题。

bool MouseFilter::eventFilter(QObject *o, QEvent *e)
{
    if(e->type() == QEvent::MouseMove)
    {
        emit signalMouseMove();
        return true;
    }else if(e->type() == QEvent::MouseButtonRelease) {
        emit signalMouseRelease();
        return true;
    }else if(e->type() == QEvent::MouseButtonPress) {
        emit signalMousePress();
        return true;
    }else if(e->type() == QEvent::MouseButtonDblClick) {
        emit signalMouseDoubleClick();
        return true;
    }
    return QObject::eventFilter(o,e);
}

MouseFilter *mf = new MouseFilter();
qApp->installEventFilter(mf);
4

1 回答 1

0

通过(解决方法)在 QApplication 调用之前添加睡眠计时器“解决”了问题。该问题似乎与使用 SSD 的超快速启动和使用注册表运行键自动启动有关,而触摸屏驱动程序似乎仍在加载。

重要提示:必须在创建 QApplication 之前进行睡眠调用,否则您只会遇到问题。

int main(int argc, char *argv[])
{
    QThread::sleep(15);

    QApplication a(argc, argv);

    if(!QDir::setCurrent(QApplication::applicationDirPath()))
            QDir::setCurrent("C:\\ApplicationPath\\");

    Translator *t = new Translator();
    a.installEventFilter(t);

    return a.exec();
}

Qt 支持建议使用 Windows 原生函数检查 GetSystemMetrics(QT_SM_DIGITIZER)。我对此进行了扩展,以获得一个漂亮的启动画面,以便用户收到正在发生的事情的通知:

static inline bool hasTouchSupport(QSysInfo::WinVersion wv)
{
    enum { QT_SM_DIGITIZER = 94, QT_NID_INTEGRATED_TOUCH = 0x1,
           QT_NID_EXTERNAL_TOUCH = 0x02, QT_NID_MULTI_INPUT = 0x40 };

    return wv < QSysInfo::WV_WINDOWS7 ? false :
        (GetSystemMetrics(QT_SM_DIGITIZER) & (QT_NID_INTEGRATED_TOUCH | QT_NID_EXTERNAL_TOUCH | QT_NID_MULTI_INPUT)) != 0;
}

int main(int argc, char *argv[])
{


    if(!hasTouchSupport(QSysInfo::windowsVersion())) {
        QApplication *ta = new QApplication(argc,argv);

        QPixmap logo("C:\\PathToLogo\\LogoTransparent.png");
        QSplashScreen splash(logo);
        splash.show();
        clock_t start = clock();
        while(30*CLOCKS_PER_SEC > clock()-start)
        {
            if(hasTouchSupport(QSysInfo::windowsVersion()))
                break;
            ta->processEvents();
            QThread::msleep(20);
        }
        splash.close();
        ta->quit();
        ta->processEvents();
        delete ta;
    }

    QApplication *a = new QApplication(argc, argv);
    //Custom Code goes here

    return a->exec();
}
于 2014-05-26T07:39:53.750 回答