每次从qml页面收到触摸事件时,如何重置计时器

时间:2017-09-12 09:45:00

标签: qt embedded qml touch-event screensaver

import QtQuick 2.6;
import QtQuick.Controls 2.1 ;
import  QtQuick.Layouts 1.3 ;

Page{
    id: page
    width:  800
    height: 1024
    background:   Rectangle { 
        color: "black" ;
        anchors.fill:parent ;
    }

    Rectangle {

        id:rect1

        x: 0
        y:10
        width: 100
        height: 100
        color :  "red"

        MouseArea {

           anchors.fill: parent
           onClicked: tmr.restart()
        }

    }

    Rectangle {

        id:rect2
        x: 0
        y:110
        width: 100
        height: 100
        color :  "blue"
       MouseArea {
           anchors.fill: parent
           onClicked: tmr.restart()
        }

    }

    Timer {

     id : tmr 
     interval : 30000
     repeat : true 
     running: true
     onTriggered: {

           console.log ("hello world ")

     }

   }
}  

我使用qt框架为嵌入式imx6 freescale设备开发了一个软件。

基本上我只是想在每次点击时重新启动计时器,每次在屏幕上看到触摸事件时,无论点击/触摸发生在我的矩形的鼠标区域内还是在我们的外部。

这个想法类似于屏幕保护程序。

1 个答案:

答案 0 :(得分:3)

有多种方式,正确的方式取决于您的要求。

如果您不需要保证计时器在输入期间触发,您可以在所有内容之上分层MouseArea。在此MouseArea中,您处理了pressed - 信号,但不是accept

这允许您稍后处理较低层中的鼠标输入。但是,只有当新的按键发生时,您才会意识到Timer可能会触发,例如在一个半小时的手指移动输入期间。

第二种方法是让所有MouseArea报告通过其处理信号,信号发生,重置Timer。对于所有未处理的信号,你将MouseArea层叠在其他所有信号之下,处理所有信号以捕捉掉掉的信号。

借助C ++,您可以在Item - 树的根目录创建Item,并覆盖childMouseEventFitler
有关详细信息,请参阅我的回答here

在这种情况下,您应该在MouseArea内添加Item,因此它可以在任何地方过滤。

  

注意!此方法将针对您点击下可能存在的每个MouseArea触发。但在你的场景中,我猜这很好。

感谢 GrecKo 我再次调查了一般eventFilter,确实很容易。

  1. 您在单例模式后创建一个简单的QObject,在其中重新实现eventFilter - 方法,以便它发出信号
  2. <强> mouseeventspy.h

    #pragma once
    #include <QObject>
    #include <QtQml>
    #include <QQmlEngine>
    #include <QJSEngine>
    
    
    class MouseEventSpy : public QObject
    {
        Q_OBJECT
    public:
        explicit MouseEventSpy(QObject *parent = 0);
    
        static MouseEventSpy* instance();
        static QObject* singletonProvider(QQmlEngine* engine, QJSEngine* script);
    
    protected:
        bool eventFilter(QObject* watched, QEvent* event);
    
    signals:
        void mouseEventDetected(/*Pass meaningfull information to QML?*/);
    
    };
    

    <强> mouseeventspy.cpp

    #include "mouseeventspy.h"
    #include <QQmlEngine>
    #include <QJSEngine>
    #include <QEvent>
    
    MouseEventSpy::MouseEventSpy(QObject *parent) : QObject(parent)
    {
        qDebug() << "created Instance";
    }
    
    // This implements the SINGLETON PATTERN (*usually evil*)
    // so you can get the instance in C++
    MouseEventSpy* MouseEventSpy::instance()
    {
        static MouseEventSpy* inst;
        if (inst == nullptr)
        {
            // If no instance has been created yet, creat a new and install it as event filter.
            // Uppon first use of the instance, it will automatically
            // install itself in the QGuiApplication
            inst = new MouseEventSpy();
            QGuiApplication* app = qGuiApp;
            app->installEventFilter(inst);
        }
        return inst;
    }
    
    // This is the method to fullfill the signature required by
    // qmlRegisterSingletonType.
    QObject* MouseEventSpy::singletonProvider(QQmlEngine *, QJSEngine *)
    {
        return MouseEventSpy::instance();
    }
    
    // This is the method is necessary for 'installEventFilter'
    bool MouseEventSpy::eventFilter(QObject* watched, QEvent* event)
    {
        QEvent::Type t = event->type();
        if ((t == QEvent::MouseButtonDblClick
             || t == QEvent::MouseButtonPress
             || t == QEvent::MouseButtonRelease
             || t == QEvent::MouseMove)
                && event->spontaneous() // Take only mouse events from outside of Qt
                )
            emit mouseEventDetected();
        return QObject::eventFilter(watched, event);
    }
    
    1. 然后将它作为单身类型注册到QML,如下所示:
    2. <强>的main.cpp

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include "mouseeventspy.h"
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);
      
          QQmlApplicationEngine engine;
      
          qmlRegisterSingletonType<MouseEventSpy>("MouseEventSpy", 1, 0, "MouseEventSpy", MouseEventSpy::singletonProvider);
      
          // We do this now uppon creation of the first instance.
          // app.installEventFilter(MouseEventSpy::instance());
      
          engine.load(QUrl(QStringLiteral("main.qml")));
      
          return app.exec();
      }
      
      1. 现在在QML中,您可以在必要的文件中导入单例的实例并使用信号,例如重置Timer
      2. <强> main.qml

        import QtQuick 2.6
        import QtQuick.Window 2.2
        import MouseEventSpy 1.0
        
        Window {
            visible: true
            width: 640
            height: 480
            title: qsTr("Hello World")
        
            Connections {
                target: MouseEventSpy
                onMouseEventDetected: myTimer.restart()
            }
        
            Timer {
                id: myTimer
                interval: 1000
                onTriggered: console.log('It has been 1 seconds since the last mouse event')
            }
        
            Text {
                anchors.center: parent
                text: myTimer.running ? 'Timer is Running\nMove the mouse to reset'
                                      : 'Move the Mouse to make the timer run again.'
            }
        
        }