szumial
szumial

Reputation: 73

How to automatically update a statusbar message?

I am using Qt 5.15.1 and C++ to create a simple app which processes signals from hardware and displays images and driver status. I want to update the statusbar message when an int value defined in another class changes. I would like this to happen automatically, each time this value changes. I understand that I need signals and slots to achieve this. So far I have done the following:

signalprocessing.h

class SignalProcessing: public QObject
{
    Q_OBJECT
public:
    SignalProcessing(QObject *parent = nullptr);
private:
    int status;
public slots:
    int GetStatus();
signals:
    void StatusChanged();
}

signalprocessing.cpp

SignalProcessing::SignalProcessing(QObject *parent)
: QObject(parent)
{
}
int SignalProcessing::GetStatus()
{
    emit(StatusChanged());
    return status;    
}

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    virtual ~MainWindow();
    SignalProcessing *signalProcessing;
}

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    signalProcessing= new SignalProcessing(this);
    ui->statusbar->showMessage(QString::number(signalProcessing->GetStatus()));
}

The problem is that the statusbar message is currently not updated automatically, but set to a given value.

How do I make sure it will always display the current status?

Upvotes: 1

Views: 982

Answers (2)

Marek R
Marek R

Reputation: 37697

First change singal declartion so it will provide new value:

class SignalProcessing: public QObject
{
    Q_OBJECT
public:
    SignalProcessing(QObject *parent = nullptr);
private:
    int status;
public slots:
    int setStatus(int value);
signals:
    void statusChanged(const QString& message);
}

void SignalProcessing::setStatus(int value)
{
    if (status != value)
    {
        status = value;
        emit statusChanged(tr("Status is %1").arg(status));
    }
}

Then connect this signal to QStatusBar::showMessage slot and you done.

Upvotes: 0

JarMan
JarMan

Reputation: 8277

The idea is that you want to emit your StatusChanged signal when the value has actually changed, not when you call GetStatus(). So you need a SetStatus() function, and your SignalProcessing class will need to know when to call that. Then you want to connect that signal to a slot that then updates your status bar. It might look something like this:

class SignalProcessing: public QObject
{
    Q_OBJECT
public:
    SignalProcessing(QObject *parent = nullptr);
    int getStatus();
    void setStatus(int value);
private:
    int status;
signals:
    void statusChanged();  // It's better to start signals with a lower case letter
}

signalprocessing.cpp

SignalProcessing::SignalProcessing(QObject *parent)
: QObject(parent)
{
}
int SignalProcessing::getStatus()
{
    return status;    
}
void SignalProcessing::setStatus(int value)
{
    if (status != value)
    {
        status = value;
        emit statusChanged();
    }
}

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    virtual ~MainWindow();
    SignalProcessing *signalProcessing;
public slots:
    void updateStatus();
}

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    signalProcessing= new SignalProcessing(this);
    connect(signalProcessing, &SignalProcessing::statusChanged, this, &MainWindow::updateStatus);
    updateStatus();
}

void MainWindow::updateStatus()
{
    ui->statusbar->showMessage(QString::number(signalProcessing->getStatus()));
}

Upvotes: 1

Related Questions