如何在Qt中将访问时间限制为一种方法

How to limit visit times to a method in Qt?

本文关键字:方法 一种 Qt 时间 访问      更新时间:2023-10-16

有一个信号--sendMessage(),它会触发一个函数--handleMessage(),如果我在一个拍摄时间内得到信号的次数太多,就会出现一些问题,所以我要设置handleMessage()只能每500毫秒运行一次。

一些朋友可以告诉我如何实现它吗?

我这样做的方法是使成员变量bool mMessageSendPending;

接下来,我将创建一个成员变量QTimer mTimer;

在构造函数中,我会像这样设置计时器:

// Run lambda function on timer timeout
connect(&mTimer, &QTimer::timeout, [=](){
    // This code will be run by timer
    if(mMessageSendPending){
        // This will never happen more frequent than 500ms
        handleMessage();
        // Reset to be ready for next send
        mMessageSendPending=false;
    }
});
// Start timer with interval of 500 ms
mTimer.start(500);

// Run lambda function on sendMessage received
connect(&mySender, &MySenderClass::sendMessage, [=](){
    // Mark that we want to handle message.
    // This may happen more frequent than once every 500ms
    mMessageSendPending=true;
});

编辑:正如@Trevir指出的那样,这在线程边界上是不安全的。为了安全起见,建议将所有对mMessageSendPending的访问包装在具有匹配QMutexQMutexLocker中,或者将QAtomicInteger包装以创建"原子布尔值"。

处理此问题的常用方法是延迟手动处理消息,例如照常连接

connect(sender, &Sender::sendMessage, receiver, &Receiver::handleMessage);

并在接收端收集消息,使用计时器延迟

class Receiver : public QObject
{
    Q_OBJECT
public:
    void handleMessage(const QString &message);
....
private:
    QStringList m_messages;
....
};
static const int DELAY = 500;
void Receiver::handleMessage(const QString &message)
{
    const bool needsScheduling = m_messages.isEmpty();
    m_messages.append(message);
    if (needsScheduling) {
        // schedule handling messages after a delay
        // calls of handleMessage until this fires will add more messages
        // to m_messages
        QTimer::singleShot(DELAY, this, [this]() {
            // do whatever you need to do with the messages
            qDebug() << m_messages;
            // clean up
            m_messages.clear();
        });
    }
}

QML中的另一种解决方案:

Timer {
    id: timer
    property real period: 1000
    property real started: 0
    interval: 10
    running: true
    repeat: true
    onTriggered: {
        var s = new Date().getTime();
        if((s - timer.started) > timer.period)
        {
            timer.started = s;
            handleMessage();
        }
    }
    function handleMessage()
    {
        console.log("handleMessage");
    }
}

handleMessage()调用频率不超过 1000 毫秒,尽管onTriggered()每 10 毫秒调用一次。

相关文章: