问题描述
我想在运行时使用QAbstractListModel
设置Qt Quick应用程序的主窗口的x / y位置和宽度/高度。我有一个模型,它可以与Repeater
和delegate
一起使用,但是我不知道如何在委托人外部访问它。
这是我的代码:
model.h:
#ifndef MODEL_H
#define MODEL_H
#include <QAbstractListModel>
#include <QVector>
class Model : public QAbstractListModel {
Q_OBJECT
public:
int rowCount(const QModelIndex&) const override;
QVariant data(const QModelIndex& index,int role) const override;
public slots:
void insert(QObject& item);
void insert(QObject* item);
void remove(QObject* item);
void clear();
protected:
QHash<int,QByteArray> roleNames() const override;
private:
QVector<QObject*> mItems;
};
#endif // MODEL_H
rectangleclass.h:
#ifndef RECTANGLECLASS_H
#define RECTANGLECLASS_H
#include <QQuickItem>
class RectangleClass : public QObject
{
private:
Q_OBJECT
Q_PROPERTY(int xPos READ xPos WRITE setXPos NOTIFY xPosChanged)
Q_PROPERTY(int yPos READ yPos WRITE setYPos NOTIFY yPosChanged)
int m_xPos;
int m_yPos;
public:
RectangleClass () {}
int xPos() const { return m_xPos; }
int yPos() const { return m_yPos; }
public slots:
void setXPos(int arg)
{
if (m_xPos == arg)
return;
m_xPos = arg;
emit xPosChanged(arg);
}
void setYPos(int arg)
{
if (m_yPos == arg)
return;
m_yPos = arg;
emit yPosChanged(arg);
}
signals:
void xPosChanged(int arg);
void yPosChanged(int arg);
};
#endif // RECTANGLECLASS_H
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>
#include <iostream>
#include "model.h"
#include "rectangleclass.h"
int main(int argc,char *argv[])
{
QGuiApplication app(argc,argv);
Model* internalModel = nullptr;
internalModel = new Model;
RectangleClass* newObj = nullptr;
newObj = new RectangleClass;
newObj->setXPos(500);
newObj->setYPos(500);
std::cout << "xPos: " << newObj->xPos() << " yPos: " << newObj->yPos() << std::endl;
internalModel->insert(newObj);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("internalModel",internalModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
model.cpp:
#include "model.h"
int Model::rowCount(const QModelIndex&) const {
return mItems.size();
}
QVariant Model::data(const QModelIndex& index,int /*role*/) const {
QObject* item = mItems.at(index.row());
return QVariant::fromValue(item);
}
void Model::insert(QObject& item) {
beginInsertRows(QModelIndex(),0);
mItems.push_front(&item);
endInsertRows();
}
void Model::insert(QObject* item) {
beginInsertRows(QModelIndex(),0);
mItems.push_front(item);
endInsertRows();
}
void Model::remove(QObject* item) {
for (int i = 0; i < mItems.size(); ++i) {
if (mItems.at(i) == item) {
beginRemoveRows(QModelIndex(),i,i);
mItems.remove(i);
endRemoveRows();
break;
}
}
}
void Model::clear() {
if (!mItems.isEmpty())
{
beginRemoveRows(QModelIndex(),mItems.size()-1);
mItems.clear();
endRemoveRows();
}
}
QHash<int,QByteArray> Model::roleNames() const {
QHash<int,QByteArray> roles;
roles[Qt::UserRole + 1] = "item";
return roles;
}
main.qml:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
x: 500 //internalModel.data(0).xPos
y: 500 //internalModel.data(0).yPos
width: 1640
height: 1480
title: qsTr("Hello World")
Rectangle {
x: 450
y: 450
width: 50
height: 50
color:"red"
}
Repeater {
model: internalModel
delegate: Rectangle {
x: modelData.xPos
y: modelData.yPos
width: 400
height: 400
color:"yellow"
Text {
anchors.centerIn: parent
text: "X-Position: " + modelData.xPos + " Y-Position: " + modelData.yPos
}
}
}
}
解决方法
我认为您需要放弃整个模型/中继器的想法。只需直接公开您的RectangleClass。
RectangleClass* newObj = new RectangleClass;
newObj->setXPos(500);
newObj->setYPos(500);
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("rectModel",newObj);
然后在QML中,您只需访问属性即可。
Rectangle {
x: rectModel.xPos
y: rectModel.yPos
width: 400
height: 400
color:"yellow"
Text {
anchors.centerIn: parent
text: "X-Position: " + rectModel.xPos + " Y-Position: " + rectModel.yPos
}
}