每次从 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
,果然很简单
- 你按照单例模式创建了一个简单的
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);
}
- 比起像这样将它注册为单例类型到 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 中,您可以在必要的文件中导入单例实例并使用信号,例如重置
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.'
}
}
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
,果然很简单
- 你按照单例模式创建了一个简单的
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);
}
- 比起像这样将它注册为单例类型到 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 中,您可以在必要的文件中导入单例实例并使用信号,例如重置
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.'
}
}