【问题标题】:Qt Auto Connect New Object's Signal to Existing SlotQt 自动将新对象的信号连接到现有插槽
【发布时间】:2013-11-06 15:58:12
【问题描述】:

我有一个简单的对象库,用于存储有关变量的附加数据。当我创建每个对象(用作变量)时,我想维护这些对象的 QList。有没有办法自动将所有新创建的对象的信号连接到一个插槽。该插槽属于我的应用程序中的一个对象。

对象头 ezbool.h

class EZBool : public QObject
{
    Q_OBJECT
public:
    explicit EZBool(QObject *parent = 0);
    EZBool(QString boolName, bool initialValue, IOTYPE type);   
    //Removed Member Functions      
signals:
    void localEZBool_Created(EZBool *me);
private:
    QString name;
    bool value;
    IOTYPE ioType;
};

对象构造器 ezbool.cpp

EZBool::EZBool(QString boolName, bool initialValue, IOTYPE type)
{
    name = boolName;
    value = initialValue;
    ioType = type;
    emit localEZBool_Created(this);
}

插槽实现 fbtest.cpp

void TestFB::on_localEZBool_Created(EZBool *newVar)
{
    qDebug() << "Auto Connect worked??";
    //Handle new variable by adding to QList
}

fbtest.cpp中以下列方式创建对象:

void TestFB::initialize()
{
    mpOnCmd     = new EZBool("MpOnCmd", false, IO_INPUT);
    zeroSpeed   = new EZBool("ZeroSpeed", false, IO_INPUT);

}

我尝试过匹配 Qt 的自动连接功能,但没有成功。自动连接能力引用自以下:

Automatic Connections

Qt Project Forums

我不想在实例化每个新对象后手动连接每个信号。方式如下:

connect(ezBool, SIGNAL(localEZBool_Created(EZBool*)),
        this, SLOT(on_localEZBool_Created(EZBool*)));

有没有人有任何建议或建议?谢谢!

【问题讨论】:

  • 我实际上无法解决问题。如果您需要在列表中存储新对象,为什么不在创建后立即将它们添加到列表中并希望使用信号/插槽呢?
  • 我希望这发生在幕后,因为它是自动处理的。我当然理解你的建议。此应用程序旨在创建“基本模板”。用户修改越简单越好 - 在这种情况下,必须进行显式调用以将新对象添加到列表中并不简单。

标签: qt signals-slots qt-signals


【解决方案1】:

您可以在 TestFB 中覆盖 childEvent,然后对 ChildAdded 做出反应

void TestFB::childEvent(QChildEvent * event)
{
    if(event.added())
    {
        EZBool child = qobject_cast<EZBool*>(event.child());
        if(child)
        {
            qDebug() << "Auto Connect worked??";
            //Handle new variable by adding to QList
        }
    }
}

这需要将 EZBool 的父级设置为TestFB(最好在构造函数中)

mpOnCmd     = new EZBool("MpOnCmd", false, IO_INPUT, this);
zeroSpeed   = new EZBool("ZeroSpeed", false, IO_INPUT, this);

并在自定义构造函数中添加QObject *parent=0参数并将其传递给超类

EZBool::EZBool(QString boolName, bool initialValue, IOTYPE type, QObject p)
: QObject(p)
{
    name = boolName;
    value = initialValue;
    ioType = type;
}

【讨论】:

  • this 还没有实际创建时,在构造函数中发出像emit localEZBool_Created(this); 这样的信号是否安全?
  • 可能没有,除此之外还没有连接任何东西
  • @ratchetfreak 非常感谢您的选择。这是实施我的解决方案的唯一已知方法吗? Qt Child Created Doc 解释说您的选择肯定会满足我的需要。虽然这是一种替代解决方案,但我仍然很想知道是否有办法将特定对象类型的所有信号(无论创建的实例如何)连接到指定的插槽。示例:当 EZBool 信号 Y 发出时,任何 EZBool 实例将始终连接到 TestFB Slot X。这有意义吗?
【解决方案2】:

为了解决对象列表自动填充问题,我根本不会使用信号/槽机制。它实际上似乎是对 QObject 的过度杀伤和不必要的依赖。相反,我会提出以下解决方案,IMO 更简单。

定义将存储新创建对象的列表。您可以随时阅读:

static QList<EZBool *> Objects;

EZBool 类将自动使用新创建的对象填充列表:

class EZBool
{
public:    
    EZBool(QString boolName, bool initialValue, IOTYPE type)
        :
            name(boolName),
            value(initialValue),
            ioType(type)
    {
        Objects.push_back(this);
    }
private:
    QString name;
    bool value;
    IOTYPE ioType;
};

这个类负责创建新的 EZBool 对象。

class TestFB
{
public:
    void initialize()
    {
        new EZBool("MpOnCmd", false, IO_INPUT);
        new EZBool("ZeroSpeed", false, IO_INPUT);
    } 
};

【讨论】:

  • 感谢您的建议。我同意这将在正常结构中工作。也许我应该包含更多关于环境的信息。 TestFB 是我的应用程序中的类,EZBool 是我创建的“EZIO”静态库中的类。 EZBool 不会知道 Objects QList 是什么,因为它不是 EZIO 库的成员。
  • 我最初希望每当实例化一个新的 EZBool 时,我可以让 EZIO 库的成员 EZBool 发出一个 ObjectCreated 信号。我希望在应用程序中有一个插槽 NewBool​​Created 将连接到从 EZBool 对象发出的 ObjectCreated 信号。现在,我相信我的想法可能由于您和@ratchetfreak 提到的其他原因而行不通。
猜你喜欢
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
相关资源
最近更新 更多