C'è un modo per utilizzare qualsiasi funzione C++ come uno slot Qt, senza che la classe erediti da QWidget?Utilizzo di qualsiasi funzione C++ come slot Qt
risposta
Non è possibile in Qt versioni < Qt 5.
Per poter utilizzare i segnali/slot il compilatore oggetto meta deve essere invocati. Per rendere questo accada la classe deve soddisfare i seguenti requisiti:
- Eredita da
QObject
o di qualsiasi altra sottoclasse (ad esempioQWidget
,QPushButton
ecc) - Il
Q_OBJECT
macro dovrebbe essere definito nella sezione privata della classe al fine per attivare funzioni metaoggetto come slot - Utilizza gli
Qt
paroleslots
esignals
per dichiarare quali funzioni dovrebbe essere maniglie nel meta compilatore come fessure o segnali
Per ulteriori dettagli controllare le pagine della documentazione corrispondenti sulla e signals & slots
controllare anche la documentazione QObject
:
noti che la macro
Q_OBJECT
è obbligatoria per qualsiasi oggetto che implementa segnali, fessure o proprietà. È inoltre necessario eseguire il compilatore di oggetti Meta nel file di origine. Si consiglia vivamente di utilizzare di questa macro in tutte le sottoclassi di QObject indipendentemente dal fatto che o non utilizzino effettivamente segnali, slot e proprietà, dal momento che l'errore su può portare alcune funzioni a mostrare comportamenti strani.
Modifica: A partire da Qt 5, i funtori e le espressioni lambda possono essere utilizzati come slot. Vedi New Signal Slot Syntax in Qt 5
È importante notare che, sebbene ciò non sia possibile in Qt 4, sta andando per essere possibile in Qt 5, utilizzando il nuovo meccanismo segnale/slot. http://qt-project.org/wiki/New_Signal_Slot_Syntax – leinir
Hai ragione, ma IMHO dovrebbe essere usato solo in rari casi. L'utilizzo degli slot è più elegante rispetto all'utilizzo di tr1 :: bind con funzioni semplici. – pnezis
sono assolutamente d'accordo, dovrebbero essere un caso raro. Un po 'come le dichiarazioni brevi di cirquit, sono utili in un insieme molto ristretto di circostanze e in questi casi aumentano la leggibilità e la facilità di manutenzione. Ma, dovrebbero essere usati solo allora, non come regola generale. – leinir
Improbabile. Il compiler Qt-meta-object (moc) include la funzione, sono contrassegnati come slot -s, in code-wrapper relativamente grande. I file, creati da moc, iniziano con moc_, guardali.
È sufficiente ereditare QObject: http://qt-project.org/doc/qt-4.8/signalsandslots.html
In Qt 5, è possibile. Vedi http://qt-project.org/wiki/New_Signal_Slot_Syntax
In Qt 4, questo non è supportato direttamente ma ci sono un paio di librerie che forniscono questa funzionalità collegando il segnale tramite uno slot in un QObject nascosto che chiama la funzione non-slot. Il mio tentativo a questo può essere trovato a https://github.com/robertknight/qt-signal-tools. Ci sono collegamenti ad altre implementazioni nella parte inferiore del README.
A partire da Qt 5, i funtori e le espressioni lambda possono essere utilizzati come slot (come precedentemente menzionato, qui: http://qt-project.org/wiki/New_Signal_Slot_Syntax).
Come io non riuscivo a trovare codice di esempio, ho aggiunto il seguente:
Questo esempio utilizza boost::function
per un membro della classe ClassName::classMember()
senza parametri.
boost::function<void()> f= boost::bind(&ClassName::classMember, classInstance);
connect(QObjectInstance, &QObject::signalName, f);
Quando il segnale e la classe membro Qt dispone di parametri (ad esempio ClassName::classMember(int)
), la funzione boost deve essere adattato nel modo seguente:
boost::function<void(int)> f= boost::bind(&ClassName::classMember, classInstance, _1);
Maggiori informazioni sul boost :: bind può essere trovato nel documentazione: http://www.boost.org/doc/libs/1_55_0/libs/bind/bind.html
Non sono sicuro se è duplicato, ma questo potrebbe aiutare: http://stackoverflow.com/questions/8533906/ –