每当我从qml页面收到触摸事件时,如何重置计时器 [英] How can I reset a timer every time I receive a touch event from a qml page

查看:288
本文介绍了每当我从qml页面收到触摸事件时,如何重置计时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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飞思卡尔设备的软件。

I develop a software for embedded imx6 freescale device using qt framework.

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

Basically I just want to restart my timer every time I click and every time I get a touch event on my screen whether the click/touch happen inside the mouse area of my rectangles or outside of them.

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

The idea is similar to a screensaver.

推荐答案

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

There are multiple ways, and the right way depends on your requirements.

如果您不需要保证计时器在输入过程中触发,则可以在 MouseArea 。在此 MouseArea 中,您可以处理按下的信号,但不要接受它们。

If you don't need to guarantee that the timer triggers during a input you can just layer a MouseArea on top of everything. In this MouseArea you handle the pressed-signals, but dont accept them.

这允许您稍后在较低层中处理鼠标输入。但是,只有在发生新新闻时,您才意识到,计时器可能会触发例如在半个小时的手指输入过程中。

This allows you to handle the mouse input in the lower layers later. However you only realize whenever a new press happens, and the Timer might trigger e.g. during a half-an-hour finger-move input.

第二种方法是获取所有 MouseArea 的报告响应其已处理的信号,即信号已发生,以重置 Timer 。对于所有未处理的信号,请将 MouseArea 放置在其他所有内容下面,处理所有信号以捕获发生的故障。

The second way is to have all MouseAreas report uppon their handled signals, that the signal happend, to reset the Timer. For all unhandled signals, you layer a MouseArea beneath everything else, handle all signals there to catch what has been falling through.

重新排序为C ++,您可以在 Item -树的根目录中创建 Item ,并覆盖 childMouseEventFitler

查看我的答案 此处 > 有关此内容的更多信息。

Resorting to C++ you might create a Item at the root of your Item-tree, and override the childMouseEventFitler
See my answer here for more on this.

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

In this case you should add a MouseArea right inside this Item, so it has something to filter at any place.


注意!此方法将为您可能点击的每个 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 ,的确很简单。


Thanks to GrecKo I looked into the general eventFilter again, and indeed it is really easy.


  1. 您可以按照单例模式创建一个简单的 QObject ,在其中您重新实现 eventFilter -方法,这样它将发出信号

  1. you create a simple QObject following the singleton pattern, in which you reimplement the eventFilter-method, so that it will emit a signal

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中,您可以在必要的文件中导入单例实例并使用信号,例如重置计时器

  1. Now in QML you can import the instance of the singleton in the necessary files and use the signal, e.g. to reset a 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.'
    }

}

这篇关于每当我从qml页面收到触摸事件时,如何重置计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆