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

How can I reset a timer every time I receive a touch event from a qml page

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设备开发了一个软件。

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

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

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

如果您不需要保证计时器在输入期间触发,您可以在所有内容之上添加一个 MouseArea。在此 MouseArea 中,您处理 pressed 信号,但不要 accept 它们。

这允许您稍后在较低层处理鼠标输入。但是,您只会在新的印刷机发生时才意识到,并且 Timer 可能会触发,例如在半小时的手指移动输入中。

第二种方法是让所有 MouseArea 报告它们处理的信号,即信号发生,以重置 Timer。对于所有未处理的信号,您将 MouseArea 层置于其他所有信号之下,在那里处理所有信号以捕获掉落的信号。

借助 C++,您可以在 Item 树的根部创建一个 Item,并覆盖 childMouseEventFitler
有关更多信息,请参阅我的回答

在这种情况下,您应该在 Item 中添加一个 MouseArea,这样它就可以在任何地方进行过滤。

Note! This method will be triggered for each MouseArea that might be under your click. But in your scenario, this would be fine, I guess.


多亏了GrecKo 我又看了下将军eventFilter,果然很简单

  1. 你按照单例模式创建了一个简单的 QObject,在其中你重新实现了 eventFilter 方法,这样它就会发出一个信号

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:

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

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.'
    }

}