【问题标题】:How to automatically update a statusbar message?如何自动更新状态栏消息?
【发布时间】:2020-11-10 13:01:21
【问题描述】:

我正在使用 Qt 5.15.1 和 C++ 创建一个简单的应用程序,它处理来自硬件的信号并显示图像和驱动程序状态。当另一个类中定义的 int 值发生更改时,我想更新状态栏消息。我希望每次这个值发生变化时自动发生这种情况。我知道我需要信号和插槽来实现这一点。到目前为止,我已经完成了以下工作:

信号处理.h

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

信号处理.cpp

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

主窗口.h

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

主窗口.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()));
}

问题是状态栏消息目前没有自动更新,而是设置为给定值。

如何确保它始终显示当前状态?

【问题讨论】:

  • 确实,这可以使用signals and slots 来实现。您必须将StatusChanged 信号连接到更新状态栏的插槽。
  • 这是否意味着来自 SignalProcessing 类的信号和 MainWindow 类中的插槽?我知道 QStatusBar 有一个名为“showMessage”的公共插槽,它适合这个目的。但是,我如何确保该值是由信号传递的?
  • SignalProcessingMainWindow 之间的连接是最简单的解决方案。如果参数类型匹配,则可以直接连接到showMessage

标签: c++ qt statusbar


【解决方案1】:

这个想法是您希望在值实际更改时发出StatusChanged 信号,而不是在您调用GetStatus() 时。所以你需要一个 SetStatus() 函数,你的 SignalProcessing 类需要知道什么时候调用它。然后你想将该信号连接到一个插槽,然后更新你的状态栏。它可能看起来像这样:

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
}

信号处理.cpp

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

主窗口.h

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

主窗口.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()));
}

【讨论】:

  • 感谢@JarMan,这就是我一直在做的事情,它与 Qt 文档中给出的示例一致。但是,我一定是在 SignalProcessing 代码中做错了,因为状态没有更新,即使我强制驱动程序设置失败或故意将状态值设置为某个整数(例如 -1)。
  • 您包括对connect的调用?
  • 是的。我可以通过调试观察到 setStatus() 方法没有在进程中调用,并且应该是发出 statusChanged() 信号的对象。我相信这是因为我没有在 SignalProcessing 类的任何地方调用 setStatus() 方法。相反,我只是为状态 int 赋值(示例): status = McGetParamInt(channel, MC_Elapsed_Pg, &elapsedPages);
  • 对,只要值发生变化,你就可以调用 setStatus 了。
  • 好的!明白了:)谢谢你的解决方案!我看到要实现我需要的东西,我必须在很多地方调用 setStatus() 方法,我认为它可能会影响性能,我觉得这不是一个优雅的解决方案。我可能不得不重新考虑我的 UI 中此状态栏的用途。
【解决方案2】:

首先更改信号声明,以便提供新值:

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));
    }
}

然后将此信号连接到QStatusBar::showMessage 插槽即可。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多