Я пытаюсь сделать часть своего приложения сценарием.
У меня есть объект «GraphLogic», который содержит таблицу указателей на объекты «Блок». Я хочу иметь доступ к этому объекту в моем скрипте.
#include <QObject>
#include <QString>
class Block;
class GraphLogic: public QObject
{
Q_OBJECT
public:
explicit GraphLogic( int Heads, int Rows)
virtual ~GraphLogic();
…
Q_INVOKABLE int getLines() const;
Q_INVOKABLE int getColumns() const;
Q_INVOKABLE Block* getBlock(int Col, int Row);
QString exportSeq(const QString& rScript);
…
QList< QList< Block*> > m_BlockTable;
};
реализация (graphlogic.cpp):
#include "graphlogic.h"#include "block.h"
#include <QJSEngine>
#include <QQmlEngine>
GraphLogic::GraphLogic(int Col, int Rows){
for(int ColIndex = 0; ColIndex < Col; ++ ColIndex)
{
m_BlockTable.append(QList<Block*>());
for(int Index = 0; Index < Rows; ++Index)
{
m_BlockTable[ColIndex].append(nullptr);
}
}
}
GraphLogic::~GraphLogic()
{
for(int ColIndex = 0; ColIndex < m_BlockTable.size(); ++ ColIndex)
{
for(int Index = 0; Index < m_BlockTable[0].size(); ++Index)
{
if(m_BlockTable[ColIndex][Index])
{
delete m_BlockTable[ColIndex][Index];
m_BlockTable[ColIndex][Index] = nullptr;
}
}
}
}
int GraphLogic::getLines() const
{
return m_BlockTable[0].size();
}
int GraphLogic::getColumns() const
{
return m_BlockTable.size();
}
Block* GraphLogic::getBlock(int Col, int Row)
{
if(Col < 0 || Col >= m_BlockTable.size() || Row < 0 || Row >= m_BlockTable[0].size())
{
return nullptr;
}
return m_BlockTable[Col][Row];
}
bool GraphLogic::addBlock(Block* pBlock, int Row, int Col)
{
if(Col < 0 || Col >= m_BlockTable.size() || Row < 0 || Row >= m_BlockTable[0].size())
{
return false;
}
m_BlockTable[Col][Row] = pBlock;
}QString GraphLogic::exportSeq(const QString& rScript)
{
QJSEngine engine;
qmlRegisterType<Block>();
//this ->Logic object
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
QJSValue LogicValue = engine.newQObject(this);
engine.globalObject().setProperty("Logic", LogicValue);
QJSValue SeqStr = engine.evaluate(rScript);
QJSValue Res = SeqStr.call();
return Res.toString();
}
я сделал Блок :: GetLabel () Метод сценариев, а также.
Вот блок учебный класс
block.h:
#include <QObject>
class Block: public QObject
{
Q_OBJECT
public:
Block(const QString &rLabel);
virtual ~Block();
Q_INVOKABLE QString getLabel() const;
private:
QString m_Label;
};
и block.cpp:
#include "block.h"
Block::Block(const QString &rLabel)
: m_Label(rLabel)
{
}
Block::~Block()
{
}
QString Block::getLabel() const
{
return m_Label;
}
Я могу сделать свой объект «GraphLogic» доступным для скрипта, он отлично работает.
Когда я пытаюсь получить доступ к объекту блока, я могу получить метки блока, скрипт завершается и нормально завершает работу.
Macro.qs (передается как параметр GraphLogic :: экспорт):
(function logicToString()
{
var Out;
var i, j;
for(i = 0; i < Logic.getColumns(); ++i)
{
for(j = 0; j < Logic.getLines(); ++j)
{
if(Logic.getBlock(i,j) != null)
{
// b is Block* !
var b = Logic.getBlock(i,j);
Out += b.getLabel();
}
Out += ";";
}
Out += "\n";
}
return Out;
})
Но когда я пытаюсь получить доступ блок объекты снова, он падает. Вот пример, main.cpp:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include "graphlogic.h"#include "block.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
GraphLogic Logic(3,3);
Block* pNewBlock = new Block("first");
Logic.addBlock(pNewBlock, 0,0);
pNewBlock = new Block("second");
Logic.addBlock(pNewBlock, 1,1);
QString JSFile("./Macro.qs");
QFile ScriptFile(JSFile);
if(ScriptFile.open(QIODevice::ReadOnly))
{
QTextStream Stream(&ScriptFile);
QString ExportScript = Stream.readAll();
//output:
//"first;0;0;\n0;second;0;\n0;0;0;\n"qDebug() << Logic.exportSeq(ExportScript);
}
ScriptFile.close();
Block* pBlock = Logic.getBlock(0,0);
if(pBlock)
{
//crash SEG FAULT
qDebug()<< pBlock->getLabel();
}
return a.exec();
}
Возможно, потому что они были уничтожены из QJSEngine?
Я сказал это, потому что та же самая проблема произошла, когда я забыл явно объявить право собственности на GraphLogic объект быть QQmlEngine :: CppOwnership.
Итак, я полагаю, что мне нужно найти способ предотвратить QJSEngine уничтожить блок объект. Такой же как QQmlEngine :: setObjectOwnership но в JavaScript, потому что у меня нет доступа к текущему блоку за пределами сценария.
Есть идеи, как мне этого добиться?
Спасибо,
Задача ещё не решена.
Других решений пока нет …