首先,我创建了一个带有成员函数的新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的报告错误,但我不知道如何解决我的问题。任何想法,如何,教程或什么来解决我的问题?
谢谢和问候:)
答案 0 :(得分:1)
我运行了你的代码并重现了你的错误但是你最终想要做什么?
您的代理人表示您要从C ++注入一些包含name
和color
的模型项,否则,为什么要使用GridView
,是否正确?
如果情况并非如此,那么下面的内容可能并不那么有用,或者可能是它的一些变体。所以我继续构建了一个我认为你可能要完成的事情的例子。
总之,在我的系统上,在创建任意数量的模型项(在本例中为20)之后,可滚动的GridView
委托(沿着滚动范围的中间)看起来像这样:
正如我所说的,似乎你想要将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();
}
希望这有帮助!