一篇文章搞懂qt图形视图框架setRect和setPos函数的意义

setRect()函数

三个坐标系我就不多说了,view原点默认在左上角,scene和item的原点默认都在中心位置。
注意:此函数并不能设置一个item的位置,我的理解是当一个item调用该函数时,会构建一个一个item的坐标系,参数x,y代表这个item原点的坐标位置(基于item自身的坐标系),w和h不用多说,代表宽高。举个例子:

在这里插入图片描述

setPos()函数

item调用此函数,表示把item自身的坐标原点移动到场景坐标的x,y处,例如,item->setPos(0,0),对于设置不同rect的item,最终显示的位置也不一样。
在这里插入图片描述
当场景中的item进行移动时,item的rect是不会改变的,即在自己的item类中调用rect(),值是不会改变的,改变的是pos属性,例如,当外部拖动进一个item到view中,如果希望item中心位置在鼠标位置处然后创建显示,可以设置item->setRect(-w/2,-h/2,w,h),然后setPos(mousepos),就可以实现。

关于场景scene的setSceneRect的思考

这个也是同理,其实函数创建的是一个场景的坐标系。即
如果希望场景原点和视图原点重合:scene->setScene(0,0,w,h);注意w和h是view最新的宽高,如果小于view的宽高,场景原点可能不会和view重合,原因以后在研究。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一份完整的QT代码来实现残缺棋盘覆盖问题的可视化: ```cpp #include <QtWidgets/QApplication> #include <QtWidgets/QMainWindow> #include <QtWidgets/QGraphicsView> #include <QtWidgets/QGraphicsScene> #include <QtCore/QPointF> #include <QtCore/QRectF> #include <QtCore/QRandomGenerator> #include <QtCore/QVector> #include <QtCore/QDebug> // 棋盘大小 const int BOARD_SIZE = 8; // 残缺块的位置和大小 const int BLOCK_X = 2; const int BLOCK_Y = 3; const int BLOCK_SIZE = 2; // 棋盘格子大小 const int CELL_SIZE = 60; // 骨牌大小 const int TILE_SIZE = CELL_SIZE / 2; // 棋盘颜色 const QColor BOARD_COLOR = QColor(64, 64, 64); // 骨牌颜色 const QColor TILE_COLOR = QColor(192, 192, 192); // L型骨牌形状 const QVector<QPointF> L_TILE_SHAPE = QVector<QPointF>() << QPointF(0, 0) << QPointF(CELL_SIZE, 0) << QPointF(CELL_SIZE, TILE_SIZE) << QPointF(TILE_SIZE, TILE_SIZE) << QPointF(TILE_SIZE, CELL_SIZE) << QPointF(0, CELL_SIZE); // 棋盘类 class Board : public QGraphicsItem { public: Board() { // 设置边界 setRect(0, 0, BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE); } QRectF boundingRect() const override { return rect(); } void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override { // 绘制棋盘 painter->setPen(Qt::NoPen); painter->setBrush(BOARD_COLOR); painter->drawRect(rect()); // 绘制残缺块 painter->setBrush(Qt::white); painter->drawRect(BLOCK_X * CELL_SIZE, BLOCK_Y * CELL_SIZE, BLOCK_SIZE * CELL_SIZE, BLOCK_SIZE * CELL_SIZE); } }; // 骨牌类 class Tile : public QGraphicsItem { public: Tile(const QColor& color) : m_color(color) { // 随机选择L型骨牌的方向和位置 int orientation = QRandomGenerator::global()->bounded(4); int x = QRandomGenerator::global()->bounded(BOARD_SIZE - 1); int y = QRandomGenerator::global()->bounded(BOARD_SIZE - 1); // 根据方向和位置确定骨牌的形状和位置 QVector<QPointF> shape = L_TILE_SHAPE; switch (orientation) { case 0: setPos((x + 1) * CELL_SIZE, y * CELL_SIZE); break; case 1: setPos(x * CELL_SIZE, (y + 1) * CELL_SIZE); shape = QVector<QPointF>() << QPointF(0, 0) << QPointF(CELL_SIZE, 0) << QPointF(CELL_SIZE, -TILE_SIZE) << QPointF(TILE_SIZE, -TILE_SIZE) << QPointF(TILE_SIZE, -CELL_SIZE) << QPointF(0, -CELL_SIZE); break; case 2: setPos(x * CELL_SIZE, (y + 1) * CELL_SIZE); shape = QVector<QPointF>() << QPointF(0, -CELL_SIZE) << QPointF(TILE_SIZE, -CELL_SIZE) << QPointF(TILE_SIZE, -TILE_SIZE) << QPointF(CELL_SIZE, -TILE_SIZE) << QPointF(CELL_SIZE, 0) << QPointF(0, 0); break; case 3: setPos(x * CELL_SIZE, y * CELL_SIZE); shape = QVector<QPointF>() << QPointF(0, -TILE_SIZE) << QPointF(TILE_SIZE, -TILE_SIZE) << QPointF(TILE_SIZE, 0) << QPointF(CELL_SIZE, 0) << QPointF(CELL_SIZE, CELL_SIZE) << QPointF(0, CELL_SIZE); break; } // 设置骨牌的形状和颜色 m_shape = shape; } QRectF boundingRect() const override { return QRectF(0, 0, CELL_SIZE, CELL_SIZE); } void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override { // 绘制骨牌 painter->setPen(Qt::NoPen); painter->setBrush(m_color); painter->drawPolygon(m_shape); } private: QColor m_color; QVector<QPointF> m_shape; }; // 残缺棋盘覆盖算法 void cover(QGraphicsScene* scene, int x, int y, int size) { static int tileIndex = 0; // 如果棋盘大小为1,直接返回 if (size == 1) { return; } // 检查残缺块的位置 if (x <= BLOCK_X && BLOCK_X < x + size && y <= BLOCK_Y && BLOCK_Y < y + size) { // 分成4个部分,递归求解 int newSize = size / 2; cover(scene, x, y, newSize); cover(scene, x + newSize, y, newSize); cover(scene, x, y + newSize, newSize); cover(scene, x + newSize, y + newSize, newSize); } else { // 在棋盘上随机选取一个位置,放置骨牌 Tile* tile = new Tile(TILE_COLOR); tile->setZValue(tileIndex++); tile->setPos((x + QRandomGenerator::global()->bounded(size - 1)) * CELL_SIZE, (y + QRandomGenerator::global()->bounded(size - 1)) * CELL_SIZE); scene->addItem(tile); // 分成4个部分,递归求解 int newSize = size / 2; cover(scene, x, y, newSize); cover(scene, x + newSize, y, newSize); cover(scene, x, y + newSize, newSize); cover(scene, x + newSize, y + newSize, newSize); } } int main(int argc, char* argv[]) { QApplication a(argc, argv); // 创建主窗口和场景 QMainWindow mainWindow; QGraphicsScene scene(0, 0, BOARD_SIZE * CELL_SIZE, BOARD_SIZE * CELL_SIZE); QGraphicsView view(&scene, &mainWindow); mainWindow.setCentralWidget(&view); // 添加棋盘和骨牌 Board board; scene.addItem(&board); cover(&scene, 0, 0, BOARD_SIZE); // 调整视图大小和位置 view.fitInView(board, Qt::KeepAspectRatio); view.centerOn(board); // 显示窗口 mainWindow.show(); return a.exec(); } ``` 在这个代码中,我们使用QT中的QGraphicsView和QGraphicsScene来实现可视化。我们先创建一个棋盘的图形项(Board),然后用一个名为cover的递归函数来实现残缺棋盘覆盖算法。在每个递归步骤中,我们要么将棋盘分成四个部分,要么在棋盘上放置一个L型骨牌。我们使用QT中的QGraphicsItem和QPainter来绘制棋盘和骨牌。 在主函数中,我们创建一个主窗口,并将QT视图(view)设置为主窗口的中央窗口。我们添加棋盘和骨牌,并调整视图的大小和位置,最后显示窗口。 希望这个代码能够帮助您实现残缺棋盘覆盖问题的QT可视化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值