将信号和槽连接到QSharedPointer内的对象

10

我的应用程序包含了一些类似于这样的功能:

void SomeClass::set_data_provider(DataProvider *data_provider)
{
    connect(data_provider, SIGNAL(data_available(int)),
        this, SLOT(data_available(int)));
}
为了避免传递裸指针,我已将所有出现DataProvider *的地方更改为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中传递的对象?

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自带的connect函数的自动补全功能。

P.S. 对我而言,我不会修改你的代码。我认为它很好 :)


这很有趣,我不知道你可以这样做。然而,我认为它并没有改进原始代码。使用QMetaData / qRegisterMetaType更加整洁,因为这正是机制的原因:),此外,您还可以保留自动完成:)) - code_fodder
我认为 OP 提出的问题并不是关于如何通过信号槽机制发送 QSharedPointer 对象(在这种情况下,应该使用 qRegisterMetaType),而是如何将 QSharedPointer 对象传递给 connect 函数。 - hank
但是,“如何通过信号槽发送QSharedPointer”和“如何将QSharedPointer对象传递给connect函数”实质上是相同的,因为connect是信号槽机制的一部分。但无论如何,我非常喜欢您所做的事情,它超越了传统思维,但我仅仅是在指出这不是最好的方法(或许只是我的个人看法)。 - code_fodder

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

没有 lambda 的爱? - iKlsR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接