Search code examples
c++qtqwidgetqt-signals

Qt: Force a repaint to update text from fast button clicks?


I have some very simple code that displays a QPushButton which, when clicked, updates a spinbox with a random number 1 - 100. The problem is I can click the button many times in quick succession and only see one or two updates in the spinbox.

How can I repaint the spinbox for each click on the QPushButton? I've verified that I am firing and catching multiple click signals, but Qt doesn't repaint most of them.

So far I've tried calling repaint(), repaint() on all parent widgets, sendPostedEvents(), and processEvents().

#include <QtWidgets/QWidget>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QLayout>

#include <random>
#include <ctime>

class QtBtnEx : public QWidget
{
    Q_OBJECT

public:
    QtBtnEx(QWidget *parent = 0);

    QPushButton* btn;
    QSpinBox* spin;

public slots:
    void onClicked();
};


QtBtnEx::QtBtnEx(QWidget *parent)
    : QWidget(parent)
{

    btn = new QPushButton("button");
    spin = new QSpinBox();

    btn->setFixedSize(90, 30);
    spin->setFixedSize(90, 30);

    this->setLayout(new QVBoxLayout());
    this->layout()->setAlignment(Qt::AlignCenter);
    this->layout()->addWidget(btn);
    this->layout()->addWidget(spin);


    connect(btn, &QPushButton::clicked, this, &QtBtnEx::onClicked);
}

//Fires for every button click but does not paint for every click
void QtBtnEx::onClicked()
{
    srand(time(nullptr));
    spin->setValue(rand() % 100);
}

Solution

  • Found my problem; I had the call to srand(time(nullptr)) in the slot code. It was responsible for the delays I was seeing. Pulled it up top and the spinbox refreshes immediately.

    #include <QtWidgets/QWidget>
    #include <QtWidgets/QPushButton>
    #include <QtWidgets/QSpinBox>
    #include <QtWidgets/QLayout>
    
    #include <random>
    #include <ctime>
    
    class QtBtnEx : public QWidget
    {
        Q_OBJECT
    
    public:
        QtBtnEx(QWidget *parent = 0);
    
        QPushButton* btn;
        QSpinBox* spin;
    
    public slots:
        void onClicked();
    };
    
    
    QtBtnEx::QtBtnEx(QWidget *parent)
        : QWidget(parent)
    {
        srand(time(nullptr));
    
        btn = new QPushButton("button");
        spin = new QSpinBox();
    
        btn->setFixedSize(90, 30);
        spin->setFixedSize(90, 30);
    
        this->setLayout(new QVBoxLayout());
        this->layout()->setAlignment(Qt::AlignCenter);
        this->layout()->addWidget(btn);
        this->layout()->addWidget(spin);
    
    
        connect(btn, &QPushButton::clicked, this, &QtBtnEx::onClicked);
    }
    
    void QtBtnEx::onClicked()
    {
        spin->setValue(rand() % 100);
    }