将信号和槽附加到 QSharedPointer 中的对象
Attaching signals and slots to an object within a QSharedPointer
我的应用程序包含几个这样的函数:
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 中传递的对象?
您可以创建自定义连接函数:
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 对本机连接功能的自动完成功能。
P.S。至于我,我不会更改您的代码。我觉得还行:)
为了完整起见,这里是@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);
}
我的应用程序包含几个这样的函数:
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 中传递的对象?
您可以创建自定义连接函数:
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 对本机连接功能的自动完成功能。
P.S。至于我,我不会更改您的代码。我觉得还行:)
为了完整起见,这里是@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);
}