QObject,qRegisterMetaType和私有拷贝构造函数的子类

时间:2009-06-05 14:57:41

标签: qt4

我有一个类是QObject的子类,我想将其注册为元类型。 QObject documentation表示复制构造函数应该是私有的,但QMetaType documentation表示类型应该具有公共默认构造函数,公共复制构造函数和公共析构函数

我可以覆盖QObject的私有拷贝构造函数并声明一个公共拷贝构造函数,但是这是安全/ ok /对吗?

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

5 个答案:

答案 0 :(得分:16)

将QObject的复制构造函数公开是不安全的。但是,您可以将类指针注册为元类型。即:

Q_DECLARE_METATYPE(MyClass的*);

这就是Qt用QObject和QWidget处理它的方式。

答案 1 :(得分:5)

你所要求的是完全正常的。您不能在复制构造函数的实现中使用QObject的复制构造函数(它是私有的),但是再一次,没有人会强迫您:

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

根据QObject所需的服务,您需要在复制文件和复制分配操作符中复制other的某些属性。例如,如果你使用QObject的动态属性功能,你也需要复制它们:

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

同样,如果你想保持信号/插槽连接。

答案 2 :(得分:0)

我使用单独的copyValue(const MyClass & other)函数来复制定义MyClass实例的“值”的数据成员。这确保了我不会打破QObject唯一标识的假设,同时仍然能够复制在编译时定义的类的部分。

答案 3 :(得分:-1)

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

答案 4 :(得分:-1)

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