У меня есть программа, работающая на платформе Android.Он содержит класс MapRenderView, производный от QQuickItem.Все работает хорошо, кроме MapRenderView.MapRenderView хорошо работает на win10, но ничего не рендерит на платформе Android.Как это понять?Я пытаюсь масштабировать изображение в моем телефоне, что-то, что я вижу, что-то, что я хочу отрендерить, но мой палец должен касаться экрана телефона (все прошло после того, как мой палец покинул экран).Вот MapRenderView:
// .h
class MapRenderView: public QQuickItem
{
Q_OBJECT
...
public:
MapRenderView(QQuickItem *parent = nullptr);
~MapRenderView();
...
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData);
void wheelEvent(QWheelEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private:
void initVertices() noexcept;
void initMatrix() noexcept;
QColor m_color;
QVector<QPointF> m_points;
QMatrix m_matrix;
QMatrix m_initMatrix; // matrix for reset when double click
qreal m_width;
QPoint m_mousePos;
qreal m_size;
qreal m_minSize;
qreal m_maxSize;
bool m_matrixHasInit;
MapLoader *m_mapLoader;
QSGGeometryNode *m_node;
QSGGeometry *m_geometry;
signals:
void matrixChanged();
void matrixInitFinished();
private slots:
void slotWidthChanged();
};
// .cpp
MapRenderView::MapRenderView(QQuickItem *parent)
: QQuickItem (parent)
, m_color (Qt::blue)
, m_width (0)
, m_mousePos (0, 0)
, m_size (1.0)
, m_minSize (0.5)
, m_maxSize (4.0)
, m_matrixHasInit (false)
, m_node (nullptr)
, m_geometry (nullptr)
{
setFlag(QQuickItem::ItemHasContents);
setClip(true);
setFocus(true);
setAcceptedMouseButtons(Qt::AllButtons);
setAcceptHoverEvents(true);
connect(this, SIGNAL(widthChanged()), this, SLOT(slotWidthChanged()));
...
initVertices();
}
MapRenderView::~MapRenderView()
{
}
void MapRenderView::initMatrix() noexcept
{
m_width = width();
qreal xOffset = m_mapLoader->getLeftEdgePos() + m_mapLoader->getMapWidth() * 0.5;
qreal yOffset = m_mapLoader->getBottomEdgePos() + m_mapLoader->getMapHeight() * 0.5;
qreal xScaleRatio = width() / m_mapLoader->getMapWidth();
qreal yScaleRatio = height() / m_mapLoader->getMapHeight();
qreal scaleRatio = xScaleRatio > yScaleRatio ? yScaleRatio : xScaleRatio;
m_matrix.translate(width() * 0.5, height() * 0.5);
m_matrix.scale(0.95, 0.95);
m_matrix.scale(scaleRatio, scaleRatio);
m_matrix.scale(1, -1);
m_matrix.translate(-xOffset, -yOffset);
m_initMatrix = m_matrix;
emit matrixInitFinished();
}
void MapRenderView::initVertices() noexcept
{
const QVariantMap &lineMap = m_mapLoader->getLineMap();
const QVariantMap &nodeMap = m_mapLoader->getNodeMap();
for (auto &item: lineMap)
{
auto valueMap = item.toMap();
const QString& startNodeId = valueMap.value("startNodeId").toString();
const QString& endNodeId = valueMap.value("endNodeId").toString();
int startPosX = nodeMap.value(startNodeId).toMap().value("x").toInt();
int startPosY = nodeMap.value(startNodeId).toMap().value("y").toInt();
int endPosX = nodeMap.value(endNodeId).toMap().value("x").toInt();
int endPosY = nodeMap.value(endNodeId).toMap().value("y").toInt();
m_points.push_back(QPointF(startPosX, startPosY));
m_points.push_back(QPointF(endPosX, endPosY));
}
}
void MapRenderView::slotWidthChanged()
{
if (m_width == 0.0 || width() <= 0)
return;
qreal ratio = width() / m_width;
m_width = width();
m_matrix.scale(ratio, ratio);
emit matrixChanged();
m_initMatrix.scale(ratio, ratio);
update();
}
QPointF MapRenderView::mapStationPos(QMatrix matrix, qreal x, qreal y)
{
QPointF pos = matrix.map(QPointF(x, y));
return pos;
}
QSGNode *MapRenderView::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *updatePaintNodeData)
{
if (!m_matrixHasInit)
{
m_matrixHasInit = true;
initMatrix();
}
Q_UNUSED(updatePaintNodeData);
int pointSize = m_points.size();
if (!oldNode)
{
m_node = new QSGGeometryNode;
m_geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), pointSize);
m_geometry->setLineWidth(2);
m_geometry->setDrawingMode(QSGGeometry::DrawLines);
QSGGeometry::Point2D *vertices = m_geometry->vertexDataAsPoint2D();
for (int index = 0; index < pointSize; ++index)
{
QPointF point = m_matrix.map(m_points[index]);
vertices[index].set(
float(point.x()),
float(point.y())
);
}
m_node->setGeometry(m_geometry);
m_node->setFlag(QSGNode::OwnsGeometry);
QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
material->setColor(m_color);
m_node->setMaterial(material);
m_node->setFlag(QSGNode::OwnsMaterial);
}
else
{
m_node = static_cast<QSGGeometryNode *>(oldNode);
m_geometry = m_node->geometry();
m_geometry->allocate(pointSize);
QSGGeometry::Point2D *vertices = m_geometry->vertexDataAsPoint2D();
for (int index = 0; index < pointSize; ++index)
{
QPointF point = m_matrix.map(m_points[index]);
vertices[index].set(
float(point.x()),
float(point.y())
);
}
}
m_node->markDirty(QSGNode::DirtyGeometry);
return m_node;
}
void MapRenderView::wheelEvent(QWheelEvent *event)
{
int delta = event->delta();
if (event->orientation() == Qt::Vertical)
{
qreal scaleRank = delta > 0 ? 1.05 : 0.95;
m_size *= scaleRank;
if (m_size < m_minSize)
{
m_size = m_minSize;
scaleRank = 1;
}
else if (m_size > m_maxSize)
{
m_size = m_maxSize;
scaleRank = 1;
}
if (scaleRank == 1.0)
return;
m_matrix.scale(scaleRank, scaleRank);
emit matrixChanged();
update();
}
}
void MapRenderView::mousePressEvent(QMouseEvent *event)
{
m_mousePos = event->pos();
this->setCursor(QCursor(Qt::OpenHandCursor));
event->accept();
}
void MapRenderView::mouseReleaseEvent(QMouseEvent *event)
{
event->accept();
this->setCursor(QCursor(Qt::ArrowCursor));
}
void MapRenderView::mouseMoveEvent(QMouseEvent *event)
{
event->accept();
QPoint currentPos = event->pos();
qreal deltaX = (currentPos.x() - m_mousePos.x()) * width() * 0.08 / (m_size * m_size);
qreal deltaY = (currentPos.y() - m_mousePos.y()) * width() * -0.08 / (m_size * m_size);
this->setCursor(QCursor(Qt::ClosedHandCursor));
if (deltaX == 0.0 && deltaY == 0.0)
return;
m_mousePos = currentPos;
m_matrix.translate(deltaX, deltaY);
emit matrixChanged();
QQuickItem::mouseMoveEvent(event);
update();
}
void MapRenderView::mouseDoubleClickEvent(QMouseEvent *event)
{
event->accept();
m_matrix = m_initMatrix;
emit matrixChanged();
m_size = 1.0;
update();
}
// .qml
MapRenderView {
id: mapView;
anchors.fill: parent
anchors.margins: 20
z: 20
onMatrixInitFinished: {
...
}
...
}