在 QGraphicsItem QT 中设置 X Y 坐标
Posted
技术标签:
【中文标题】在 QGraphicsItem QT 中设置 X Y 坐标【英文标题】:Set X Y Coordinates in QGraphicsItem QT 【发布时间】:2020-06-06 07:56:03 【问题描述】:用Qapplication和QGraphicsItem Library来确定一个物体的坐标,通常使用setPos
和setPos(mapToParent(yvelocity,-xvelocity))
。这些命令的问题是它们决定了物体移动的“速度”(不是它们的XY坐标!) .
那么通过什么命令我可以提供 X 和 Y 输入并且对象会转到这些坐标?
提前致谢。
【问题讨论】:
您可以检索当前位置(使用pos())并通过分别添加yvelocity
和-xvelocity
来设置新位置。
@Scheff,这是怎么做到的?可以举个例子解释一下,写个Commands吗?
类似setPos(pos() + mapToParent(yvelocity,-xvelocity))
。虽然pos()
返回QPointF,但您可以应用operator+
。 - 有合适的过载。你对向量代数有点熟悉吗?
@Scheff,是的,非常感谢,我会测试一下。
@Scheff,这是不可能的。我的代码QPointF location =this->pos(); xvelocity = .6*cos(head); yvelocity =.6*sin(head); setPos(location + mapToParent(yvelocity,-xvelocity));
与此代码输出是:QPointF(3.37262,-2.16553) QPointF(7.04894,-4.19207) QPointF(7510.47,-4139.51) QPointF( 961316,-529883) QPointF(1.92263e+06,-1.05977e+06) QPointF(7.8751e+09,-4.3408e+09) QPointF(1.57502e+10,-8.6816e+09) QPointF(3.15004e+10) ,-1.73632e+10) &........
【参考方案1】:
在我的评论中,我给出了建议:
类似于
setPos(pos() + mapToParent(yvelocity,-xvelocity))
。虽然pos()
返回QPointF,但您可以应用operator+
。 - 有合适的过载。
三思而后行,我为mapToParent()
挣扎,这对我来说似乎是错误的。
根据 OP,速度描述了一个方向。 mapToParent()
专用于将本地位置转换为父坐标系中的位置。
QPointF QGraphicsItem::mapToParent(const QPointF &point) const
将位于此项坐标系中的点point映射到其父坐标系,并返回映射后的坐标。如果 item 没有父项,point 将被映射到场景的坐标系。
所以,更好的建议可能是:
setPos(pos() + QPointF(yvelocity,-xvelocity));
我做了一个MCVE testQGraphicsItemSetPos.cc
来证明这一点:
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup data
QGraphicsScene qGScene;
QImage qImg("smiley.png");
QGraphicsPixmapItem qGItemImg(QPixmap::fromImage(qImg));
qGScene.addItem(&qGItemImg);
const qreal v = 2.0;
qreal xVel = 0.0, yVel = 0.0;
// setup GUI
QWidget qWinMain;
qWinMain.resize(320, 200);
qWinMain.setWindowTitle("QGraphicsView - Move Item");
QVBoxLayout qVBox;
QGraphicsView qGView;
qGView.setScene(&qGScene);
qVBox.addWidget(&qGView, 1);
qWinMain.setLayout(&qVBox);
qWinMain.show();
// timer for periodic update
using namespace std::chrono_literals;
QTime qTime(0, 0);
QTimer qTimerAnim;
qTimerAnim.setInterval(50ms);
// install signal handlers
QObject::connect(&qTimerAnim, &QTimer::timeout,
[&]()
// change velocity xVel and yVel alternating in range [-1, 1]
const qreal t = 0.001 * qTime.elapsed(); // t in seconds
xVel = v * std::sin(t); yVel = v * std::cos(t);
// apply current velocity to move item
qGItemImg.setPos(qGItemImg.pos() + QPointF(xVel, yVel));
);
// runtime loop
qTimerAnim.start();
return app.exec();
还有一个CMakeLists.txt
:
project(QGraphicsItemSetPos)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("$CMAKE_SOURCE_DIR")
add_executable(testQGraphicsItemSetPos testQGraphicsItemSetPos.cc)
target_link_libraries(testQGraphicsItemSetPos Qt5::Widgets)
我用它在 VS2017 中构建和启动示例:
【讨论】:
以上是关于在 QGraphicsItem QT 中设置 X Y 坐标的主要内容,如果未能解决你的问题,请参考以下文章
QT:QGraphicsView QGraphicsScene QGraphicsItem理解