Qt / QML为GridView的c ++类设置属性

时间:2013-12-25 17:21:18

标签: c++ qt gridview qml

首先,我创建了一个带有成员函数的新c ++类,它返回一个字符串:

#ifndef TESTNAME_H
#define TESTNAME_H

#include <QObject>
#include <QString>
#include <QVariant>


class testname : public QObject
{

    Q_OBJECT;

public:
    testname();
    Q_INVOKABLE QString getName();
};

#endif // TESTNAME_H


#include "testname.h"

testname::testname()
{
}


QString testname::getName() {

    return "sometext";
}

我有一个qml文件,中间只有一个文本,如下所示:

import QtQuick 1.1

Rectangle {
    width: 360
    height: 360

    Text {
        id: text1
        anchors.centerIn: parent
        text: testqml
        font.pixelSize: 12
    }
}

请注意,属性“text”是名为“testqml”的变量。此变量包含由上面显示的类的函数返回的字符串。这个代码在main.cpp中:

#include <QApplication>
#include "qmlapplicationviewer.h"
#include <testname.h>
#include <QDeclarativeContext>
#include <QDebug>

Q_DECL_EXPORT int main(int argc, char *argv[])
{
    QScopedPointer<QApplication> app(createApplication(argc, argv));


    // Create instance of "testname"
    testname *test = new testname;

    QmlApplicationViewer viewer;

    viewer.rootContext()->setContextProperty("testqml", test->getName());

    viewer.addImportPath(QLatin1String("modules"));
    viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile(QLatin1String("qml/classtest/main.qml"));
    viewer.showExpanded();

    return app->exec();
}

使用setContextProperty-Function,返回的字符串将公开给qml文件,并在正在运行的程序中正确显示。 但我实际上打算继承GridView的模型。所以我用QML中的一个列表元素创建了一个Gridview:

import QtQuick 1.1

Rectangle {
    width: 360
    height: 360

    GridView {
        id: grid_view1
        anchors.centerIn: parent
        width: 140
        height: 140
        cellHeight: 70
        delegate: Item {
            x: 5
            height: 50
            Column {
                spacing: 5
                Rectangle {
                    width: 40
                    height: 40
                    color: colorCode
                    anchors.horizontalCenter: parent.horizontalCenter
                }

                Text {
                    x: 5
                    text: name
                    anchors.horizontalCenter: parent.horizontalCenter
                    font.bold: true
                }
            }
        }
        model: ListModel {

            ListElement {
                name: testqml
                colorCode: "grey"
            }


        }
        cellWidth: 70
    }
}

变量“testqml”现在位于List的“name”字段中,在示例中为字符串。如果我使用字符串“likethis”,则会正确显示。但如果我运行我的程序(main.cpp和类保持不变),我会收到此错误:

ListElement: cannot use script for property value 
                     name: testqml 
                     ^ 

现在我被卡住了。我发现了一个类似问题#QTBUG-16289的报告错误,但我不知道如何解决我的问题。任何想法,如何,教程或什么来解决我的问题?

谢谢和问候:)

1 个答案:

答案 0 :(得分:1)

我运行了你的代码并重现了你的错误但是你最终想要做什么?

您的代理人表示您要从C ++注入一些包含namecolor的模型项,否则,为什么要使用GridView,是否正确?

如果情况并非如此,那么下面的内容可能并不那么有用,或者可能是它的一些变体。所以我继续构建了一个我认为你可能要完成的事情的例子。

总之,在我的系统上,在创建任意数量的模型项(在本例中为20)之后,可滚动的GridView委托(沿着滚动范围的中间)看起来像这样:

enter image description here

正如我所说的,似乎你想要将C ++模型中的一些QString项注入QML GridView,注意使用GridView意味着你想要一个数字的项目。在大多数情况下,您将希望从预定义的Qt模型继承,该模型自动处理几个重要细节,例如保持QML视图与模型同步,并在删除项目或添加新项目时自动更新视图

考虑到这一点,QAbstractListModel是一个方便的类,可以从中建立模型(但这不是唯一的选项,请参阅帮助文件)。乍一看,设置这个模型看起来很复杂,所以我继续定义了一个最小版本,我希望能说明你想要做什么。

下面是模型的代码(注意:我将所有代码放在.h文件中,因此不需要.m文件)。我还创建了一些注入模型的“Items”,为简单起见,使用struct Item定义如下,但这些很容易成为另一个适当定义的类的实例:

#include <QString>
#include <QColor>
#include <QDebug>
#include <QAbstractListModel>

// Create an Item so we have something to put in the model:
struct Item {
    QString name;
    QString color;
};

class testname : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit testname(QObject *parent = 0) : QAbstractListModel(parent)
    {
        // Create some items and then add to the model:
        int N = 20;
        QStringList colorNames = QColor::colorNames();
        Item* items = new Item[N];
        for (int i = 0; i < N; i++) {
            items[i].name = QString("item"+QString::number(i));
            items[i].color = colorNames[i];
            //qDebug() << items[i].name << "; " << items[i].color;
            _model<<items[i];
        }
    }

    // enum DataRoles for QAbstractListModel:
    enum DataRoles {
        NameRole = Qt::UserRole + 1,
        ColorRole
    };

    // addData() method for QAbstractListModel:
    void addData(const Item& entry) {
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        _model << entry;
        endInsertRows();
    }

    // rowCount() method for QAbstractListModel:
    int rowCount(const QModelIndex & parent = QModelIndex()) const {
        return _model.count();
    }

    // data() required for QAbstractListModel:
    QVariant data(const QModelIndex & index, int role) const {
        if ( !index.isValid() || index.row() < 0 || index.row() >= _model.count() )
            return QVariant();
        Item modelEntry = _model[index.row()];
        if (role == NameRole) {return modelEntry.name;}
        if (role == ColorRole) {return modelEntry.color;}
        return QVariant();
    }

    // roleNames() method for QAbstractListModel:
    QHash<int,QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        roles[NameRole] = "Name";
        roles[ColorRole] = "Color";
        return roles;
    }

private:
    // Below are the model items:
    QList<Item> _model;

};

接下来是QML代码,它使用上面定义的C ++模型并在main.cpp中注册为“testqml”,然后通过model:中的属性GridView进行定义。

请注意,在委托中,模型的Color和Name属性被定义为上面类中的角色名称(这些可以是您喜欢的任何标签)。为了帮助可视化正在发生的事情,模型角色非常类似于表的列,行条目对应于模型项:

import QtQuick 1.1

Rectangle {
    width: 360
    height: 360
    /* ------------------- */
    GridView {
        id: grid_view1
        anchors.centerIn: parent
        width: 140; height: 140
        cellHeight: 70
        delegate: delegateItem
        model: testqml // the C++ model is set here
        cellWidth: 70;
    }
    /* ------------------- */
    Component {
        id: delegateItem
        Item {
            x: 5; height: 50
            Column {
                spacing: 5
                Rectangle {
                    width: 40; height: 40;
                    color: Color // Note: this a role defined in the C++ model
                    anchors.horizontalCenter: parent.horizontalCenter
                }
                Text {
                    x: 5;
                    text: Name // Note: this is another role defined in the C++ model
                    anchors.horizontalCenter: parent.horizontalCenter
                    font.bold: true
                }
            }
        }
    } // end delegateItem

} // end Rectangle

然后我的main.cpp与你的几乎相同,我会继续发布它以避免任何混淆:

#include "qtquick1applicationviewer.h"
#include <QApplication>
#include "testname.h"
#include <QDeclarativeContext>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    testname *test = new testname();
    QtQuick1ApplicationViewer viewer;
    viewer.rootContext()->setContextProperty("testqml",test);

    viewer.addImportPath(QLatin1String("modules"));
    viewer.setOrientation(QtQuick1ApplicationViewer::ScreenOrientationAuto);
    viewer.setMainQmlFile(QLatin1String("qml/QMLSetProperty/main.qml"));
    viewer.showExpanded();

    return app.exec();
}

希望这有帮助!