Showing posts with label custom class. Show all posts
Showing posts with label custom class. Show all posts

Tuesday, July 5, 2011

How to display QWidget into QML

Recently in one of my project I required to embed QWidget derived class to QML scene. While its straight forward to embed QML scene to QWidget or QGraphicsScene.

It required small effort to embed QWidget derived class to QML scene. Still its not great effort and its also vary straigt forward.

All you need to do is, create new class derived from QDeclarativeItem. Create instance of required widget and add that widget to QGraphicsProxyWidget. Now we need to register this newly created class to QML using qmlRegisterType. Now we can use this class from QML which display our QWidget derived class.

Following is code that demonstrate the same. For demo I have created class which embed QLabel to QML scene.

Following code is my custom QDeclarativeItem derive class which will expose QLabel to QML scene.
#include <QDeclarativeItem>

class QLabel;

class QmlLabel : public QDeclarativeItem
{
    Q_OBJECT    
    Q_PROPERTY(QString text READ text WRITE setText)
public:
    explicit QmlLabel(QDeclarativeItem *parent = 0);
    ~QmlLabel();    

public slots:

    void setText(const QString& text);

    QString text() const;

private:

    QLabel* mLabel;
    QGraphicsProxyWidget* mProxy;

};

#include <QLabel>
#include <QGraphicsProxyWidget>

QmlLabel::QmlLabel(QDeclarativeItem *parent) :
    QDeclarativeItem(parent)
{
    mLabel = new QLabel(QString(""));
    mProxy = new QGraphicsProxyWidget(this);
    mProxy->setWidget(mLabel);
}

QmlLabel::~QmlLabel()
{
    delete mLabel;
}

void QmlLabel::setText(const QString& text)
{
    mLabel->setText(text);
}

QString QmlLabel::text() const
{
    return mLabel->text();
}

Following code demonstrate how to register above class to QML. In qmlRegisterType first argument is component uri, which is used for importing component to QML. second and third argument is version information and fourth argument is element name in QML, By using this name we can created QML element.

#include <QtDeclarative>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    qmlRegisterType<QmlLabel>("qmlLabel", 1, 0, "QmlLabel");
    QDeclarativeView viewer;
    viewer.setSource(QUrl("qml/hybrid/main.qml"));
    viewer.show();
    return app.exec();
}

Finally following is QML code. To be able to use our custom QML element we need to import component to QML using import statement.
import QtQuick 1.0
import qmlLabel 1.0

Rectangle {
    width: 360
    height: 360
    QmlLabel {         
        x:100; y:100
        text: "QML Label"
    }
}

Following is out put from above code.

Thursday, November 18, 2010

Storing custom class in QVariant

One of my friend asked me, how we can store custom class or structure in QVariant.

I gave him following sample.Posting same sample in hope it will help others as well.

#include <QCoreApplication>
#include <QPoint>
#include <QVariant>

class MyStruct
{
public:
    QString name;
    QString id;
    QPoint point;
};
Q_DECLARE_METATYPE(MyStruct)

int main(int argc, char *argv[])
{    
    qRegisterMetaType<MyStruct>("MyStruct");

    MyStruct test1;
    test1.name="test";
    test1.id = "testid";
    test1.point=QPoint(100,100);
    QVariant v;
    v.setValue<MyStruct>(test1);

    MyStruct test2 =v.value<MyStructl>();

}

If you need to serialize this variant than you will need to provide serialization method for custom class and also need to register them with metatype system using qRegisterMetaTypeStreamOperators.