12

我有一个类是 QObject 的子类,我想将其注册为元类型。QObject 文档 声明复制构造函数应该是私有的,但是QMetaType文档声明一个类型应该有一个公共的默认构造函数、一个公共的拷贝构造函数和一个公共的析构函数。

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

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

5 回答 5

19

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

Q_DECLARE_METATYPE(MyClass*);

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

于 2009-06-05T15:14:58.967 回答
6

你所要求的完全没问题。您不能QObject在复制构造函数的实现中使用 s 复制构造函数(它是私有的),但话又说回来,没有人强迫您:

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

根据您需要 from 的服务,您需要在复制 ctor 和复制赋值运算符中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() ) );
    }

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

于 2009-08-08T12:26:04.247 回答
0

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

于 2011-07-23T14:09:17.657 回答
-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);
于 2014-12-16T14:37:57.707 回答
-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;
}
于 2014-12-16T14:44:42.563 回答