10

我的应用程序包含几个这样的功能:

void SomeClass::set_data_provider(DataProvider *data_provider)
{
    connect(data_provider, SIGNAL(data_available(int)),
        this, SLOT(data_available(int)));
}

为了避免传递原始指针,我将所有出现的DataProvider *to都更改了QSharedPointer<DataProvider>。后者几乎是前者的替代品,只是您不能将 QSharedPointer 传递给QObject::connect. 我通过从 QSharedPointer 中提取一个原始指针来解决这个问题:

void SomeClass::set_data_provider(QSharedPointer<DataProvider> data_provider)
{
    connect(data_provider.data(), SIGNAL(data_available(int)),
        this, SLOT(data_available(int)));
}

这似乎工作正常,但看起来不优雅,我对像这样访问原始指针持谨慎态度。有没有更好的方法连接到 QSharedPointer 中传递的对象?

4

2 回答 2

4

您可以创建自定义连接函数:

template<class T> bool
my_connect(const QSharedPointer<T> &sender,
           const char *signal,
           const QObject *receiver,
           const char *method,
           Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender.data(), signal, receiver, method, type);
}

并像这样使用它:

QSharedPointer<MyObject> shared(new MyObject);
my_connect(shared, SIGNAL(my_signal()), this, SLOT(my_slot()));

唯一的问题是,在您和我的解决方案中,您都将失去本机连接功能的 Qt Creator 自动完成功能。

PS 至于我,我不会更改您的代码。我觉得还好:)

于 2015-02-11T08:26:04.123 回答
2

为了完整起见,这是@hank 答案的扩展。我提供了六个connect类似的功能:

  • connect_from_pointer将 QSharedPointer 作为其第一个参数,将通常QObject *作为其第三个参数。
  • connect_to_pointer将通常QObject *作为它的第一个参数和一个 QSharedPointer 作为它的第三个参数。
  • connect_pointers两个参数都采用 QSharedPointers。

每个都有两个版本:一个接受SIGNAL()/SLOT()语法,另一个接受(推荐的)函数指针。

这些在语法上很糟糕,但这是给你的模板。

template<class T>
QMetaObject::Connection connect_from_pointer(
    const QSharedPointer<T>& sender,
    const char *signal,
    const QObject *receiver,
    const char *method,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender.data(), signal, receiver, method, type);
}

template <typename Func1, typename Func2>
QMetaObject::Connection connect_from_pointer(
    const QSharedPointer<typename QtPrivate::FunctionPointer<Func1>::Object>& sender,
    Func1 signal,
    const typename QtPrivate::FunctionPointer<Func2>::Object *receiver,
    Func2 slot,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender.data(), signal, receiver, slot, type);
}

template<class T>
QMetaObject::Connection connect_to_pointer(
    const QObject *sender,
    const char *signal,
    const QSharedPointer<T>& receiver,
    const char *method,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender, signal, receiver.data(), method, type);
}

template <typename Func1, typename Func2>
QMetaObject::Connection connect_to_pointer(
    const typename QtPrivate::FunctionPointer<Func1>::Object *sender,
    Func1 signal,
    const QSharedPointer<typename QtPrivate::FunctionPointer<Func2>::Object>& receiver,
    Func2 slot,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender, signal, receiver.data(), slot, type);
}

template<class T, class U>
QMetaObject::Connection connect_pointers(
    const QSharedPointer<T>& sender,
    const char *signal,
    const QSharedPointer<U>& receiver,
    const char *method,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender.data(), signal, receiver.data(), method, type);
}

template <typename Func1, typename Func2>
QMetaObject::Connection connect_pointers(
    const QSharedPointer<typename QtPrivate::FunctionPointer<Func1>::Object>& sender,
    Func1 signal,
    const QSharedPointer<typename QtPrivate::FunctionPointer<Func2>::Object>& receiver,
    Func2 slot,
    Qt::ConnectionType type = Qt::AutoConnection)
{
    return QObject::connect(sender.data(), signal, receiver.data(), slot, type);
}
于 2015-10-22T15:04:21.387 回答