如何检查按钮按下的时间
How to check how long a button is pressed?
我正在寻找一种方法来检查按钮按下的时间!我的想法是启动一个计数器,它在pressed()
发出时开始,在released()
发出时停止。但我目前不知道如何等待发布或类似的事件。通常,我将connect()
作为具有时隙的信号,但在这种情况下两者都是时隙。也许你有一个更好的主意也许这个已经足够好了。
当pressed
。启动计时器。当released
检查计时器运行了多长时间(并停止它)。将经过的时间保存在类中的变量中。
至少这是一种方法。
发送pressed
信号时,启动计时器。发送relesed
信号时,读取计时器上经过的时间。
这是一个完整的例子,使用Qt5和一个并非史前的C++编译器:
// https://github.com/KubaO/stackoverflown/tree/master/questions/button-timer-38645219
#include <QtWidgets>
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QWidget w;
QFormLayout layout{&w};
QPushButton button{"Press Me"};
QLabel label;
layout.addRow(&button);
layout.addRow(&label);
QElapsedTimer timer;
QObject::connect(&button, &QPushButton::pressed, [&]{ timer.start(); });
QObject::connect(&button, &QPushButton::released, [&]{
label.setText(QStringLiteral("Pressed for %1 ms").arg(timer.elapsed()));
});
w.show();
return app.exec();
}
当然,你可以把所有的变量都推到一个类中。您会注意到,C++11使这种转换几乎是无需思考的:它是经过设计的,而不是巧合。
#include <QtWidgets>
class Widget : public QWidget {
QFormLayout layout{this};
QPushButton button{"Press Me"};
QLabel label;
QElapsedTimer timer;
public:
Widget() {
layout.addRow(&button);
layout.addRow(&label);
connect(&button, &QPushButton::pressed, [&]{ timer.start(); });
connect(&button, &QPushButton::released, [&]{
label.setText(QStringLiteral("Pressed for %1 ms").arg(timer.elapsed()));
});
}
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Widget w;
w.show();
return app.exec();
}
通常不赞成在UI对象中包含"业务逻辑",因此我们可以将功能划分为Timer
、Widget
和Controller
。所有这些对象外部的代码设置了必要的连接。
#include <QtWidgets>
class Timer : public QObject {
Q_OBJECT
QElapsedTimer timer;
public:
Q_SLOT void start() { timer.start(); }
Q_SLOT void stop() { emit elapsed(timer.elapsed()); }
Q_SIGNAL void elapsed(qint64);
};
class Widget : public QWidget {
Q_OBJECT
QFormLayout layout{this};
QPushButton button{"Press Me"};
QLabel label;
public:
Widget() {
layout.addRow(&button);
layout.addRow(&label);
connect(&button, &QPushButton::pressed, this, &Widget::pressed);
connect(&button, &QPushButton::released, this, &Widget::released);
}
Q_SIGNAL void pressed();
Q_SIGNAL void released();
Q_SLOT void setText(const QString & text) { label.setText(text); }
};
class Controller : public QObject {
Q_OBJECT
public:
Q_SLOT void elapsed(qint64 ms) {
emit hasText(QStringLiteral("Pressed for %1 ms").arg(ms));
}
Q_SIGNAL void hasText(const QString &);
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Timer t;
Widget w;
Controller c;
w.show();
//
QObject::connect(&w, &Widget::pressed, &t, &Timer::start);
QObject::connect(&w, &Widget::released, &t, &Timer::stop);
QObject::connect(&t, &Timer::elapsed, &c, &Controller::elapsed);
QObject::connect(&c, &Controller::hasText, &w, &Widget::setText);
return app.exec();
}
#include "main.moc"
当然,你可以大声说,即使控制器没有真正耦合到其他代码,它仍然在一定程度上依赖于代码其余部分的设计。值得庆幸的是,事实并非如此:lambdas让简单的改编变得简单。
我们也可以使用由我们的大企业供应商提供的"外国"控制器:
// use Timer and Widget from preceding example
#include <sstream>
#include <string>
#include <functional>
class Controller {
public:
using callback_t = std::function<void(const std::string&)>;
Controller(callback_t && callback) : callback{std::move(callback)} {}
void onElapsed(int ms) {
std::stringstream s;
s << "Pressed for " << ms << " ms";
callback(s.str());
}
private:
callback_t callback;
};
int main(int argc, char ** argv) {
QApplication app{argc, argv};
Timer t;
Widget w;
Controller c{ [&](const std::string & s){ w.setText(QString::fromStdString(s)); } };
QObject::connect(&w, &Widget::pressed, &t, &Timer::start);
QObject::connect(&w, &Widget::released, &t, &Timer::stop);
QObject::connect(&t, &Timer::elapsed, [&](qint64 ms) { c.onElapsed(ms); });
w.show();
return app.exec();
}
#include "main.moc"
上面的所有示例都是可编译的:将其中任何一个放入main.cpp
,重新构建项目,然后执行。
当你发布问题的测试用例时,你应该倒退:你从这个答案末尾的某个地方开始,然后朝着开始的方向努力,最小限度地设置。它也将帮助您更好地理解自己的代码,因为冗长程度已降至最低。我希望,这说明第一个版本和最后一个版本都有相同的功能
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 从持续时间构造std::chrono::system_clock::time_point
- 问:如何使用C++中的按钮从窗口打开窗口
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- while循环中while循环的时间复杂度是多少
- 使用简单类型列表实现的指数编译时间.为什么
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在已经使用Git的情况下减少编译时间
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 从文本文件中读取时钟时间和事件时间并进行处理
- 具有未知值时的时间复杂性
- 问题:如何将某些按钮冻结一段特定的时间
- Android-如何获得创建按钮的时间
- 当按下按钮需要更长的时间时,窗口会变暗
- Windows API:为什么按钮悬停效果会在一段时间后卡住
- 如果通过按钮或时间更改执行,Maya API 的行为会有所不同
- 在对话框中禁用按钮控件需要一些时间
- 如何检查按钮按下的时间