【问题标题】:Qt-App on Windows Boot: Touchscreen generates mouse move to but no clickWindows 启动上的 Qt-App:触摸屏生成鼠标移动到但没有点击
【发布时间】:2014-05-24 10:27:56
【问题描述】:

我们有一个 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);

【问题讨论】:

    标签: c++ windows qt runonce


    【解决方案1】:

    通过(解决方法)在 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();
    }
    

    【讨论】:

    • 虽然这似乎在大多数情况下都有帮助,但如果某些东西延迟了触摸屏驱动程序的加载,它可能会失败......
    • 在新的编辑中,我们保留了 30 秒的初始屏幕,用于初始化触摸屏,一旦可用,我们就会立即转移到真正的应用程序。 bugreports.qt-project.org/browse/QTBUG-37225
    猜你喜欢
    • 2013-08-05
    • 2018-04-23
    • 2018-05-20
    • 2012-11-29
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    相关资源
    最近更新 更多