There is a set of buttons, when clicked, the slot will be executed:

void uRent::s1(const QString &i) { QString line = ui->lineEdit->text(); index = line.indexOf('_'); line.replace(index, 1, i); ui->lineEdit->setText(line); QTimer* btimer = new QTimer(this); btimer->setSingleShot(true); btimer->setInterval(200); connect(btimer, &QTimer::timeout, [this, btimer](){ QString line = ui->lineEdit->text(); line.replace(index, 1, '*'); ui->lineEdit->setText(line); btimer->deleteLater(); }); btimer->start(); } 

As you can see when the slot is executed, a timer signal is generated and that calls another function (slot) to perform. In general, everything works well, but when you quickly press the buttons, the timer signal does not have time to be processed and, as it were, skips. Apparently the signal received from pressing the button becomes in the signal queue before the timer signal. How can I clear the queue or put a block of signals before the timer slot runs?

    1 answer 1

    Since many quick clicks are supposed, the use of QTimer may be excessive. However, if you make it a member of a class, activate and stop without deleting an object, then the losses will be insignificant. However, you can consider the low-level timer approach (in the context of Qt):

     class uRent : public QObject { Q_OBJECT public: explicit uRent(QObject *parent = Q_NULLPTR) : QObject(parent), _timer_id(0), _index(-1) {} virtual ~uRent() {} void s1(const QString &i); protected: virtual void timerEvent(QTimerEvent *event); private: int _timer_id, _index; private slots: void onReplace(); }; void uRent::s1(const QString &i) { if(_timer_id > 0) { killTimer(_timer_id); _timer_id = 0; onReplace(); } QString line = ui->lineEdit->text(); _index = line.indexOf('_'); if(_index == -1) return; line.replace(_index, 1, i); ui->lineEdit->setText(line); _timer_id = startTimer(200); } void uRent::timerEvent(QTimerEvent *event) { if(event->timerId() == _timer_id) { killTimer(_timer_id); _timer_id = 0; onReplace(); } } void uRent::onReplace() { ui->lineEdit->setText(ui->lineEdit->text().replace(_index, 1, '*')); } 

    Each new click will stop the previous timer, if it didn’t manage to work, perform the planned work immediately, and finally, start a new timer cycle.