2015-02-10 6 views
6

Meine Anwendung enthalten mehrere Funktionen wie folgt aus:Anbringen Signale und Slots auf ein Objekt innerhalb eines QSharedPointer

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

roh Zeiger vorbei Um zu vermeiden, um ich alle Vorkommen von DataProvider *-QSharedPointer<DataProvider> geändert haben. Letzteres ist fast ein Ersatz für den ersten, außer dass Sie keinen QSharedPointer an QObject::connect übergeben können. Ich arbeitete, um diesen durch einen rohen Zeiger aus dem QSharedPointer Extrahieren:

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

Dies scheint gut zu funktionieren, aber es sieht unelegant und ich bin vorsichtig die Rohzeiger wie diese zugreifen. Gibt es eine bessere Möglichkeit, eine Verbindung zu einem Objekt herzustellen, das in einem QSharedPointer weitergegeben wird?

Antwort

2

können Sie erstellen eine benutzerdefinierte verbinden Funktion:

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

Und es wie folgt verwenden:

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

Das einzige Problem ist, dass beide in Ihre und meine Lösungen, die Sie Qt Creator zur automatischen Vervollständigung verlieren wird die native Verbindungsfunktion.

P.S. Was mich betrifft, ich würde deinen Code nicht ändern. Ich denke, es ist in Ordnung :)

+0

Das ist interessant, ich wusste nicht, dass Sie das tun könnten. Ich glaube jedoch nicht, dass es das Original verbessert. Es ist viel aufgeräumter, QMetaData/qRegisterMetaType zu verwenden, da dies genau der Grund für den Mechanismus ist:), und Sie behalten auch Ihre Auto-Vollendung :)) –

+0

Ich nehme an, das OP fragte nicht, wie man 'QSharedPointer'-Objekte über Signal-Slot sendet Mechanismus (in diesem Fall sollte 'qRegisterMetaType' wirklich verwendet werden), aber wie ein' QSharedPointer'-Objekt an die 'connect'-Funktion übergeben wird. – hank

+0

Aber "wie QSharedPointer über Signal-Slot zu senden" und "wie ein QSharedPointer-Objekt an die Verbindungsfunktion übergeben" .... sind im Grunde die gleiche Sache, da connect Teil des Signal-Slot-Mechanismus ist. Aber wie auch immer, ich mag das, was du getan hast, es ist außerhalb der Box, aber ich habe nur darauf hingewiesen, dass es nicht der beste Weg ist (vielleicht nur meiner Meinung nach). –

1

Der Vollständigkeit halber ist hier eine Erweiterung von @ Hank's Antwort. Ich biete sechs connect -ähnliche Funktionen:

  • connect_from_pointer nimmt QSharedPointer als erstes Argument und den üblichen QObject * als drittes Argument.
  • connect_to_pointer nimmt das übliche QObject * als sein erstes Argument und einen QSharedPointer als sein drittes Argument.
  • connect_pointers übernimmt QSharedPointers für beide Parameter.

Es gibt zwei Versionen von jedem dieser: eine, die die SIGNAL()/SLOT() Syntax und man akzeptiert, dass die (empfohlen) Funktionszeiger akzeptiert.

Diese sind syntaktisch grauenhaft, aber das ist Vorlagen für Sie.

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

Keine Lambda Liebe? – iKlsR

Verwandte Themen