c++ - custom - signals and slots qt
¿Cómo usar SIGNAL y SLOT sin derivar de QObject? (5)
No puede usar los mecanismos de señal / ranura de Qt sin usar QObject
/ Q_OBJECT
.
En teoría, podría crear un QObject ficticio y componerlo en su clase. El maniquí reenviará las llamadas a su clase. Probablemente se encontrará con problemas con la administración de por vida, por las razones que Liz describió en su comentario.
O de otra manera para formular mi pregunta (aunque no resolvió mi problema): ''QObject :: QObject'' no puede acceder al miembro privado declarado en la clase ''QObject''
Necesito la funcionalidad SIGNALs and SLOTS en mi clase, pero supongo que no es posible sin derivar de QObject
.
class MyClass
{
signals:
importantSignal();
public slots:
importantSlot();
};
El problema parece ser que necesito derivar de QObject
para usar señales y ranuras ... pero necesito el contructor predeterminado de MyClass
. Pero no puedo construirlos debido a la siguiente característica de QObject
: No Copiar Constructor u Operador de Asignación .
Lo intenté mucho ...
Así que mi clase debería verse así:
#include <QObject>
class MyClass: public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = 0); //autogenerated by qtcreator for QObject derived class
MyClass(const MyClass * other);
signals:
importantSignal();
public slots:
importantSlot();
};
Necesito el contructor predeterminado de MyClass
.
Entonces, ¿hay alguna posibilidad de evitar que el "''QObject :: QObject'' no pueda acceder al miembro privado declarado en la clase ''QObject''" error?
¿O como alternativa hay alguna posibilidad de usar señales y ranuras sin QObject
?
Me alegro por cualquier consejo.
Si desea implementar una funcionalidad basada en eventos utilizando un patrón de señales / ranuras, pero no quiere trabajar dentro de los límites de Qt (es decir, si desea usar su clase dentro de contenedores STL, etc. que requieren constructores de copias), Sugeriría usar Boost :: señal .
De lo contrario, no, no es posible que pueda hacer lo que quiere sin derivar de QObject
ya que esa clase base es la que maneja la funcionalidad de las señales / ranuras de tiempo de ejecución de Qt.
Si desea un objeto que se puede copiar con las características de QObject
, necesita membresía (por puntero) en lugar de herencia.
Puede derivar un Handler
clase de QObject
donde los slots de Handler
llaman a SomeInterface
virtuales SomeInterface
en su elemento principal.
struct NonQObjectHandler {
virtual ~ NonQObjectHandler () {}
virtual void receive (int, float) = 0;
};
class Handler : public NonQObjectHandler {
struct Receiver;
std :: unique_ptr <Receiver> m_receiver;
void receive (int, float); // NonQObjectHandler
public:
Handler ();
Handler (const Handler &); // This is what you''re really after
};
class Handler :: Receiver : public QObject {
Q_OBJECT
private:
NonQObjectHandler * m_handler;
private slots:
void receive (int, float); // Calls m_handler''s receive
public:
Receiver (NonQObjectHandler *);
};
Handler :: Handler ()
: m_receiver (new Receiver (this))
{
}
Handler :: Handler (const Handler & old)
: m_receiver (new Receiver (this))
{
// Copy over any extra state variables also, but
// Receiver is created anew.
}
Handler :: Receiver :: Receiver (NonQObjectHandler * h)
: m_handler (h)
{
connect (foo, SIGNAL (bar (int, float)), this, SLOT (receive (int, float)));
}
void Handler :: Receiver :: receive (int i, float f)
{
m_handler -> receive (i, f);
}
Desde Qt5 puedes simplemente conectarte a cualquier función
connect(&timer, &QTimer::finished,
&instanceOfMyClass, &MyClass::fancyMemberFunction);
En Qt5, usa QObject::connect
para conectar la signal
con la slot
:
/*
QMetaObject::Connection QObject::connect(
const QObject *sender,
const char *signal,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection) const;
*/
#include <QApplication>
#include <QDebug>
#include <QLineEdit>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLineEdit lnedit;
// connect signal `QLineEdit::textChanged` with slot `lambda function`
QObject::connect(&lnedit, &QLineEdit::textChanged, [&](){qDebug()<<lnedit.text()<<endl;});
lnedit.show();
return app.exec();
}
El resultado: