0

我在我的 C++/Qt 应用程序中使用专有驱动程序 API。有一个名为“status”的对象,它本质上是一个整数值,可用于监控错误。0 值表示一切正常,负值表示特定错误。我想编写一个状态栏(使用 Qt 的QStatusBar),当我执行部分代码时,它将为我提供“状态”当前值的实时更新。我目前拥有的一个简化示例:

驱动程序接口类.h

#ifndef DRIVERINTERFACECLASS_H
#define DRIVERINTERFACECLASS_H

#include <QObject>
#include "multicam.h"

class DriverInterfaceClass : public QObject
{
    Q_OBJECT
public:
    DriverInterfaceClass(QObject *parent = nullptr);
    ~DriverInterfaceClass();

private:
    void setStatus(int value);

private:
    MCSTATUS status;

signals:
    void statusChanged(const QString& status, int timeout);
};

#endif // DRIVERINTERFACECLASS_H

驱动程序接口类.cpp

#include "driverinterfaceclass.h"

DriverInterfaceClass::DriverInterfaceClass(QObject *parent)
    : QObject(parent)
{
    setStatus(McOpenDriver(NULL));
    status = McSetParamStr(MC_CONFIGURATION, MC_ErrorLog, "error.log");
}

DriverInterfaceClass::~DriverInterfaceClass()
{
    setStatus(McCloseDriver());
}

void DriverInterfaceClass::setStatus(int value)
{
    status = value;
    QString statusStr = QString::number(status);
    emit statusChanged(statusStr, 0);
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "driverinterfaceclass.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    DriverInterfaceClass *driver;
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    driver = new DriverInterfaceClass(this);
    connect(driver, &DriverInterfaceClass::statusChanged, ui->statusbar, &QStatusBar::showMessage);
}

MainWindow::~MainWindow()
{
    delete ui;
}

我在弄清楚如何使用“status”变量的值更新状态栏时遇到问题。使用此代码,我的状态栏中没有收到任何消息。也许我在初始化变量的方式上遗漏了一些东西?

4

2 回答 2

2

原因

statusChanged信号遭受一种未被察觉的存在。换句话说,该driver对象尖叫——STATUS CHAAAAAAANGED!!!!,但没有人听到。这就是为什么。

您的代码按以下顺序执行:

driver = new DriverInterfaceClass(this);

然后,作为构造函数的一部分:

setStatus(McOpenDriver(NULL));
status = McSetParamStr(MC_CONFIGURATION, MC_ErrorLog, "error.log");

只有这样才会执行连接语句:

connect(driver, &DriverInterfaceClass::statusChanged, ui->statusbar, &QStatusBar::showMessage);

显然,信号是在连接到 的插槽setStatus 之前ui->statusbar发出的。

注意:您也可以直接设置 的值status,而无需调用setStatus, 即status = McSetParamStr(...,因此根本不会发出信号。但是,由于与上述相同的原因,改为调用 setStatus 将无济于事。

移到connect前面new会导致编译器错误,因为您无法连接到不存在的东西。

解决方案

不要从构造函数发出信号。在事件发生时执行。

于 2020-12-03T23:04:31.857 回答
1

为了满足您不变的“在设置状态时发出信号”,您需要使用setStatus(McSetParamInt(... whatever));方法,不要status = xxx;直接修改(除了setStatus方法体)。然后只需稍微更改您的 setter 函数即可发出有关要显示在以下位置的所需消息的信息QStatusBar

void DriverInterfaceClass::setStatus(int value)
{
    if (status != value)
    {
        status = value;
        emit statusChanged(myStatusValueToString(status));
    }
}

信号 decl 应该是:

signals:
    void statusChanged(const QString& msg);

myStatusValueToString只是一个简单的映射:

QString myStatusValueToString(int status)
{
  if (status == 0) return "OK";
  ... etc ...
}

连接应如下所示:

QObject::connect(driver, &DriverInterfaceClass::statusChanged, statusBar, &QStatusBar::showMessage);
于 2020-12-03T11:07:44.623 回答