2009-06-05 9 views
9

tengo una clase que es una subclase de QObject que quisiera registrarse como meta-tipo. El QObject documentation establece que el constructor de copia debe ser privada, pero el QMetaType documentation establece que un tipo debe tener un constructor público predeterminado, un constructor copia pública, y un destructor pública.subclase de QObject, qRegisterMetaType, y el constructor de copia privada

que pueden anular constructor de copia privada de QObject y declarar un constructor de copia pública, pero es este derecho seguro/ok /?

class MyClass : public QObject { 
    Q_OBJECT 
    public: 
    MyClass(); 
    MyClass(const MyClass &other); 
    ~MyClass(); 
} 
Q_DECLARE_METATYPE(MyClass); 
+1

La forma en que acabé yendo es utilizar QSharedPointer (Qt 4.5 y superiores). Q_DECLARE_METATYPE (QSharedPointer ) – darkadept

Respuesta

16

No es seguro hacer público un constructor de copia de QObject. Sin embargo, puede registrar un puntero de clase como el metatipo. es decir:

Q_DECLARE_METATYPE (MyClass *);

Así es como Qt lo maneja con QObject y QWidget.

5

Lo que estás pidiendo está perfectamente bien. No se puede utilizar QObject s constructor de copia (que es privado) en la ejecución de su constructor de copia, pero por otra parte, nadie te obliga a:

class MyClass : public QObject { 
    Q_OBJECT 
public: 
    // ... 
    MyClass(const MyClass & other) 
     : QObject(), i(other.i) {} // NOTE: calling QObject default ctor 
    // ... 
private: 
    int i; 
}; 

Según los servicios que necesita de QObject, necesita para copiar algunas propiedades desde other, tanto en el controlador de copia como en el operador de asignación de copia. Por ejemplo, si se utiliza QObject por su característica propiedades dinámicas, que había necesidad de copiar esos, también:

MyClass(const MyClass & other) 
     : QObject(), i(other.i) 
    { 
     Q_FOREACH(const QByteArray & prop, other.dynamicPropertyNames()) 
      setProperty(prop.constData(), other.property(prop.constData())); 
    } 

Del mismo modo, si se quiere mantener las conexiones de señal/ranura.

+0

derecho, que tenga sentido. Por lo tanto, es posible, pero debe ser codificado con mucho cuidado. – darkadept

0

Utilizo una función separada copyValue(const MyClass & other) para copiar los miembros de datos que definen los "valores" de la instancia MyClass. Eso asegura que no rompo la suposición de identidad única QObject, mientras sigo siendo capaz de duplicar las partes de la clase que están definidas en tiempo de compilación.

0
QTFruit fruit; 
QScriptValue scriptedFruitObject = engine.newQObject(&fruit); 
engine.globalObject().setProperty("fruit", scriptedFruitObject); 

engine.setDefaultPrototype(qMetaTypeId<QTFruit>(), 
           scriptedFruitObject); 

QScriptValue qsMetaObject = 
     engine.newQMetaObject(fruit.metaObject()); 
engine.globalObject().setProperty("eLedState", 
             qsMetaObject); 

int t = engine.evaluate("eLedState.On").toInteger(); 

engine.evaluate("fruit.fromJScript(1)"); 
engine.evaluate("fruit.fromJScript(eLedState.On)"); 

engine.evaluate("fruit.fromJScript(eLedState.TriState)"); 

//Create the ctor funtion 
QScriptValue qsFruitCtor = 
     engine.newFunction(QTFruitConstructor, 
           scriptedFruitObject); 
//Expose ctor to javascript 
engine.globalObject().setProperty("QTFruit", qsFruitCtor); 

//Create the QTFruit object 
engine.evaluate("var res = new QTFruit()"); 
engine.evaluate("res.fromJScript(eLedState.TriState)"); 


class QTFruit : public QObject 
{ 
    Q_OBJECT 

public: 
    enum eLedState { Off, On , TriState}; 
    Q_ENUMS(eLedState)  
    QTFruit(); 
    ~QTFruit(); 
    QTFruit(const QTFruit & other); 

    //QTFruit(const QTFruit& other); 

public slots: 
    void fromJScript(eLedState state); 
    //void on_inputSpinBox1_valueChanged(int value); 
    //void on_buttonClicked(); 
// void fromJScript(); 
//private: 

}; 
Q_DECLARE_METATYPE(QTFruit*) 
Q_DECLARE_METATYPE(QTFruit) 

QScriptValue QTFruitConstructor(QScriptContext * /* context */, 
          QScriptEngine *interpreter); 
+0

Y el CPP: QScriptValue QTFruitConstructor (QScriptContext */* contexto * /, QScriptEngine * intérprete) { \t // volver intérprete-> toScriptValue (nueva QTFruit()); \t // o \t retorno intérprete-> toScriptValue (QTFruit()); // pero luego se necesita el contructor copia pública } QTFruit :: QTFruit (const QTFruit y otros) : QObject() { } QTFruit :: ~ QTFruit() { } QTFruit: : QTFruit() { } void QTFruit :: fromJScript (estado eLedState) { \t int t = 0; } –

0

Y el CPP:

QScriptValue QTFruitConstructor(QScriptContext * /* context */, 
          QScriptEngine *interpreter) 
{ 
    //return interpreter->toScriptValue(new QTFruit()); 
    //or 
    return interpreter->toScriptValue(QTFruit()); //but then you need the public copy contructor 
} 

QTFruit::QTFruit(const QTFruit & other) 
: QObject() 
{ 
} 

QTFruit::~QTFruit() 
{ 
} 

QTFruit::QTFruit() 
{ 
} 

void QTFruit::fromJScript(eLedState state) 
{ 
    int t = 0; 
} 
+0

Bienvenido a StackOverflow. Si desea agregar algo a su respuesta anterior, puede editarlo. Mientras lo hace, es posible que también desee agregar alguna explicación a su código. – void

Cuestiones relacionadas