У меня есть приложение Qt Quick Controls 2. В main.qml у меня есть, кроме всего прочего холста в целях прокрутки:qml canvas, context 2d сбрасывается после каждой функции вызова js из C++
Rectangle {
id: graph
width: mainArea.width/3 - 14;
height: mainArea.height - 20;
ScrollView{
anchors.fill: parent;
Canvas {
id:canvasGraph;
width: graph.width;
height: graph.height;
property bool paintB: false;
property string colorRect: "#FFFF40";
property string name: "ELF header";
property int paintX: 0;
property int paintY: 0;
property int widthP: 160;
property int heightP: 30;
property int textX: (paintX + (widthP/2)) - 15/*func return int length of text*/;
property int textY: (paintY + (heightP/2)) + 3;
onPaint:{
if (paintB){
var ctx = canvasGraph.getContext('2d');
ctx.beginPath();
ctx.font = "normal 12px serif";
ctx.fillStyle = colorRect;
ctx.strokeRect(paintX, paintY, widthP, heightP);
ctx.fillRect(paintX, paintY, widthP, heightP);
ctx.strokeText("ELF header", textX, textY);
ctx.closePath();
ctx.save();
}
}
MouseArea{
id: canvasArea;
anchors.fill: parent;
onPressed: {
paint(mouseX,mouseY,"aaa",1);
}
}
}
}
}
Сначала я попробовал рисовать в холсте JS функции, здесь:
function paint(x, y, name, type) {
canvasGraph.paintB = true;
canvasGraph.paintX = x;
canvasGraph.paintY = y;
canvasGraph.requestPaint();
}
Эта функция вызывается нажатием мыши на холсте , Он работает хорошо, он рисует прямоугольники, один за другим. Но только одна проблема заключалась в том, что после изменения размера окна приложения все прямоугольники, кроме последнего, теряются. Но это не основная проблема, потому что она работает, и этот проспект, который я мог бы решить позже.
Для рисования диаграммы мне нужна библиотека C++ (ELFIO, для чтения файлов ELF). Так что в main.cpp у меня есть два объекта. Сначала позвольте мне вызвать из main.qml функции некоторого класса C++. Второй позволяет мне вызывать функции js из C++. Вот main.cpp:
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QScopedPointer<elfFile> elfFileObj(new elfFile);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
engine.rootContext()->setContextProperty("elfFileObj", elfFileObj.data()); //this is for calling c++ from qml
QObject *rof = engine.rootObjects().first();
elfFileObj.data()->rofS = rof; //this one is for calling js func from c++
return app.exec();
Как вы можете видеть, чтение ELF файлов является управление от объекта elfFileObj, где публичная переменная, которая держит загруженный файл ELF и переменную rofS которые удерживают объект для доступа к основным .qml to js.
В elfFileObj is Q_INVOKABLE int loadELF (QString fileName); где Q_INVOKABLE - это макрос, который гарантирует, что эта функция возможна для вызова из qml-файла. Функция:
int elfFile::loadELF(QString fileName)
{
string fileNameReal = (fileName).toStdString().substr(7);
if (!reader.load(fileNameReal.c_str())){
return -1;
}
QVariant x(30);
QVariant y(10);
QVariant name("ELF header");
QVariant type(1);
QMetaObject::invokeMethod(rofS, "paint", Q_ARG(QVariant,x), Q_ARG(QVariant,y), Q_ARG(QVariant,name), Q_ARG(QVariant,type));
y = QVariant(40);
QMetaObject::invokeMethod(rofS, "paint", Q_ARG(QVariant,x), Q_ARG(QVariant,y), Q_ARG(QVariant,name), Q_ARG(QVariant,type));
}
Я попытаюсь нарисовать два прямоугольника, один за другим. QMetaObject :: invokeMethod должен вызывать функции js, которые рисуют прямоугольник на (x, y). Другие аргументы в этот момент непригодны для использования.
Основная проблема: Это нарисовать прямоугольники на холсте, но после каждого вызова invokeMethod будет удалено холст. Поэтому на холсте всегда остается только последний прямоугольник.
У кого-нибудь есть идея, как сохранить фактическое состояние холста? Спасибо за любую помощь. Это не очень хороший код, но это мой первый опыт работы с qml.