- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有 Qt Quick Controls 2 应用程序。在 main.qml 中,除了 ScrollView 中的 Canvas 之外,我还有其他东西:
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函数绘制到canvas中,这里:
function paint(x, y, name, type) {
canvasGraph.paintB = true;
canvasGraph.paintX = x;
canvasGraph.paintY = y;
canvasGraph.requestPaint();
}
此函数是通过在 Canvas 上按下鼠标来调用的。它工作得很好,它一个接一个地绘制矩形。但只有一个问题是,在调整应用程序窗口大小后,除了最后一个以外的所有矩形都丢失了。但这不是主要问题,因为它有效并且我可以稍后解决这个问题。
要绘制图表,我需要 C++ 库(ELFIO,用于读取 ELF 文件)。所以在 main.cpp 中我有两个对象。首先允许我从一些 C++ 类的 main.qml 函数中调用。第二个允许我从 C++ 调用 js 函数。这是 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 文件的公共(public)变量和保存访问 main 的对象的变量 rofS .qml 到 js 函数。
在 elfFileObj 中是 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 应该调用在 (x,y) 上绘制矩形的 js 函数。其他参数此时不可用。
主要问题:它在 Canvas 上绘制矩形,但每次调用 invokeMethod 后 Canvas 都会被清除。所以在 Canvas 上总是只留下最后一个矩形。
有人知道如何保存 Canvas 的实际状态吗?谢谢你的帮助。这不是漂亮的代码,但这是我第一次使用 qml。
最佳答案
作为命令式绘图 API 的 Canvas 只有一个像素数据的哑缓冲区。一旦绘制调用完成,它就没有矩形或其他任何对象的概念。因此,您对它通过您的 onPaint 处理程序显示的所有内容负责。它不会从一帧到另一帧清除 Canvas 内容(作为优化),但它会(必要时)在您调整窗口大小时清除它,因为它必须分配不同大小的缓冲区。
您可以在此处看到此行为:
import QtQuick 2.6
Canvas {
id: canvasGraph;
width: 500
height: 500
property int paintY: 10;
onPaint:{
var ctx = canvasGraph.getContext('2d');
ctx.beginPath();
ctx.font = "normal 12px serif";
ctx.fillStyle = "#ff0000";
ctx.strokeRect(10, paintY, 160, 30);
ctx.fillRect(10, paintY, 160, 30);
ctx.closePath();
ctx.save();
}
Timer {
interval: 16
running: true
repeat: true
onTriggered: {
canvasGraph.requestPaint();
canvasGraph.paintY += 10
if (canvasGraph.paintY > canvasGraph.height)
canvasGraph.paintY = 10
}
}
}
尝试使用 qmlscene 运行此示例并调整窗口大小。您会注意到所有内容在调整大小时都被清除,除了它绘制的一个矩形。
因此,如果您希望保留所有矩形,那么您需要每次都在 onPaint 处理程序中绘制它们(并使用 clearRect 或其他方法来填充背景以去除不存在的东西不再属于那里,如果你正在移动东西或让它们不可见)。
另一方面,我无法直接解释为什么 invokeMethod 会导致它清除,因为您没有真正提供足够的代码。可能是它正在调整 Canvas 的大小(导致缓冲区重新分配并被清除)。无论哪种方式,鉴于上述情况,我会说它并不是那么相关。
毕竟,虽然我不了解您正在制作的内容的完整背景,但我建议 Canvas 可能不是您想要做的事情的最佳工具。您可能想查看 QQuickPaintedItem,或者(更好)使用自定义 QQuickItem 来组合您的场景,该自定义 QQuickItem 定位其他 QQuickItems(或 QSGNodes)。 Canvas(和 QQuickPaintedItem)虽然易于使用,但性能不是特别好。
关于c++ - qml Canvas ,每次从c++调用js函数后都会重置上下文2d,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41825220/
如果下一个元素的宽度超过指定布局的宽度,是否有 QML 布局或某些配置会自动将 QML 项目包装到下一行? 当我使用 QML GridLayout ,项目刚好离开窗口的边缘并被剪裁: GridLayo
如果下一个元素的宽度超过指定布局的宽度,是否有 QML 布局或某些配置会自动将 QML 项目包装到下一行? 当我使用 QML GridLayout ,项目刚好离开窗口的边缘并被剪裁: GridLayo
如何在 qml 文件之间发送变量或信号? http://i.stack.imgur.com/MChCG.png Mainwindow -> 创建组件Item2.qml MainWindow -> 创建
我正在做一些事情,我有一个名为“FloatingMenu”的类(它应该在 C++ 中管理菜单)及其在文件 FloatingMenu.qml 中用于 GUI 的 QML alter-ego。我有一个文件
我正在尝试做一些看似简单的事情,但失败了:定义一个简单的内联文本格式组件,然后用不同的文本多次实例化它。这是代码 Item { . . . Component { id: favButtonL
我可以在页面中使用 InvokeActionItem 轻松共享项目,但我需要能够在 ListView 项目中调用它。我设法触发了一个调用,但我不知道如何在触发它时添加数据。我不断收到错误消息 Invo
我如何在 QML 中检测 Window {} 之外的点击? Rectangle { id: topLevel height: 400; width: 400 Window {
我试过 : var child = grid.children[slot1]; grid.children[slot1] = grid.children[slot2]; grid.children[s
例如,我希望创建一个包含 100 个文本编辑器的 qml 窗口,如何在循环中创建它?那可能吗? 最佳答案 循环是命令式代码,所以它不是 QML,而是 Javascript 或 C++。所以当然,你可以
这是我的 QML 文件,其中包含一个文本组件: import QtQuick 2.0 Item { id: idItmWrapText Text { id: idTxt
我正在寻找一种方法来显示一个文本提示,说明预期的输入作为对用户的建议。以谷歌搜索栏为例: 是否有我缺少的属性,或者这是必须通过脚本来实现的? 最佳答案 Qt Quick 输入项上不存在该属性。您可以为
为 qml 项设置背景的最简单方法是让子矩形的 anchor 完全填满父项: Item { width: 320 height: 240 Rectangle {
我想将属性动态添加到 QML 元素: Item { id: dynamicProperty; property int first; Component.onCompleted: { /*
我用 PySide 和 QML 编写了某种安装程序。按照设计,它必须是多页的。而且我想将要从 QML 表单调用的插槽划分为不同的对象(理想情况下,划分为模块,但据我了解,带有插槽的对象必须继承 QOb
QML 中有没有办法用 opacity: 0 创建一个矩形?仍然有可见的边界?如果没有,有关如何解决它的任何建议? 谢谢 最佳答案 不,不透明度适用于项目的完整视觉方面(并且不透明度:0 使项目完全不
属性变体 a:{}似乎不起作用。 a 最终未定义,而不是一个空字典。 我对 Javascript 不是很有经验...初始化属性以保存空字典的正确方法是什么? 以下 qml 在控制台上打印“qrc:/m
我在 SO 上查看了大量关于 QML 内容边距的问题,但所有答案都指向缺少 spacing: 0 属性。我已经完成了所有这些,但仍然有一些我无法消除的奇怪空间。任何人都可以解释为什么这个 QML 代码
我有一个用于样式定义的 QML 单例,定义如下: pragma Singleton import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQu
这是以下代码的结果: 主.qml import QtQuick 2.8 Item { Reusable { index: 1234 // reusable with
属性变体 a:{}似乎不起作用。 a 最终未定义,而不是一个空字典。 我对 Javascript 不是很有经验...初始化属性以保存空字典的正确方法是什么? 以下 qml 在控制台上打印“qrc:/m
我是一名优秀的程序员,十分优秀!