我通过扩展 QQuickItem 并覆盖 updatePaintNode() 函数创建了一个自定义 QML 元素。
因为我需要沿着实时增长的时间轴绘制矩形,所以我需要为每个新帧重新绘制 GUI。
有没有办法让 updatePaintNode() 函数为每个新帧定期执行?
我试过调用 node->markDirty(QSGNode::DirtyForceUpdate)
,但没有导致定期调用 updatePaintNode() 函数。
编辑:这是我的代码的样子:
QSGNode *PianoRoll::updatePaintNode(QSGNode *n, QQuickItem::UpdatePaintNodeData *data)
{
QSGGeometryNode *node = static_cast<QSGGeometryNode *>(n);
if (!node)
{
node = new QSGSimpleRectNode(boundingRect(), Qt::white);
}
node->removeAllChildNodes();
qreal msPerScreen = 10000;
qreal pitchesPerScreen = 128;
qreal x_factor = (qreal) boundingRect().width() / msPerScreen;
qreal y_factor = (qreal) boundingRect().height() / pitchesPerScreen;
for (unsigned int i = 0; i < m_stream->notes.size(); i++)
{
shared_ptr<Note> note = m_stream->notes.at(i);
qreal left = boundingRect().left() + note->getTime() * x_factor;
qreal top = boundingRect().top() + note->getPitch() * y_factor;
qreal width;
qreal height = y_factor;
if (note->getDuration() != 0)
{
width = note->getDuration() * x_factor;
}
else
{
// TODO
width = 500 * x_factor;
}
QRectF noteRectangle = QRectF(left, top, width, height);
node->appendChildNode(new QSGSimpleRectNode(noteRectangle, Qt::black));
}
node->markDirty(QSGNode::DirtyForceUpdate);
return node;
}
最佳答案
来自updatePaintNode
的文档:
The function is called as a result of
QQuickItem::update()
, if the user has set theQQuickItem::ItemHasContents
flag on the item.
您需要做两件事:定期调用 update()
并设置标志。仅此而已。
如果您需要 update()
的报价来源,您需要 QQuickWindow::frameSwapped()
或类似的信号。这会在每一帧发出,并且恰好是每一帧。所以,这会起作用:
QSGNode * myNode = ...;
QObject::connect(window, &QQuickWindow::frameSwapped, [=](){ myNode->update(); });
关于c++ - 定期重绘 QQuickItem,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19455518/