每当我从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飞思卡尔设备的软件。
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 MouseArea
s 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.
- 您可以按照单例模式创建一个简单的
QObject
,在其中您重新实现eventFilter
-方法,这样它将发出信号
- you create a simple
QObject
following the singleton pattern, in which you reimplement theeventFilter
-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);
}
- 比起注册它作为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();
}
- 现在在QML中,您可以在必要的文件中导入单例实例并使用信号,例如重置
计时器
- 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屋!