QGraphicsItem使用setpos修改图形项的位置,内存中保存的图形项位置发送了改变,但界面却没有发生变化
时间: 2023-12-30 14:04:58 浏览: 31
使用 `setPos` 方法可以改变 `QGraphicsItem` 的位置,但是这个方法只是修改了图形项的位置属性,它并不会自动地更新图形项的位置。要使图形项在场景中移动,需要调用 `update` 方法或者重新添加该图形项到场景中。
例如,如果你想要移动一个名为 `item` 的图形项,可以这样做:
```python
item.setPos(new_x, new_y)
item.update() # 更新图形项在场景中的位置
```
或者你可以将该图形项从场景中移除,然后重新添加它:
```python
scene.removeItem(item)
item.setPos(new_x, new_y)
scene.addItem(item) # 重新添加该图形项到场景中
```
这样,图形项的位置就会被正确地更新,并且在界面上也会发生相应的变化。
相关问题
向QGraphicsItem中添加控件
如果你想在Qt的图形界面中向QGraphicsItem中添加控件,可以使用QGraphicsProxyWidget类。它可以将QWidget转换为QGraphicsItem,从而将QWidget添加到QGraphicsScene中。
以下是一个简单的示例代码,演示如何向QGraphicsItem中添加QPushButton控件:
```cpp
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
// 创建一个QGraphicsItem
QGraphicsRectItem item(0, 0, 100, 100);
item.setBrush(Qt::red);
scene.addItem(&item);
// 创建一个QPushButton控件
QPushButton *button = new QPushButton("Click Me!");
// 创建一个QGraphicsProxyWidget,将QPushButton添加到其中
QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(&item);
proxy->setWidget(button);
proxy->setPos(10, 10);
view.show();
return app.exec();
}
```
在这个示例中,我们首先创建了一个QGraphicsItem(QGraphicsRectItem),并将其添加到QGraphicsScene中。然后,我们创建了一个QPushButton控件,并使用QGraphicsProxyWidget将其添加到QGraphicsItem中。最后,我们将QGraphicsView显示出来,以便查看结果。
注意:当向QGraphicsItem中添加QWidget时,QWidget的父项应该设置为QGraphicsItem,而不是QGraphicsScene。在本例中,我们将QPushButton的父项设置为QGraphicsItem(QGraphicsRectItem)。
使用QPainterPath来绘制棋盘线条,增加棋子图形项来优化代码
好的,让我们来完善一下绘制棋盘的代码。
首先,我们需要使用 `QPainterPath` 类来绘制棋盘线条。这个类可以方便地创建、操作和渲染复杂的图形路径。我们可以通过 `moveTo()` 和 `lineTo()` 方法来指定路径上的点,然后通过 `strokePath()` 方法来绘制路径。
下面是使用 `QPainterPath` 类绘制棋盘线条的代码:
```python
class Board(QGraphicsObject):
def __init__(self, parent=None):
super().__init__(parent)
def boundingRect(self):
return QRectF(0, 0, 600, 600)
def paint(self, painter, option, widget):
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(QPen(Qt.black, 2))
path = QPainterPath()
# 绘制竖线
for i in range(1, 15):
path.moveTo(i * 40, 40)
path.lineTo(i * 40, 560)
# 绘制横线
for i in range(1, 15):
path.moveTo(40, i * 40)
path.lineTo(560, i * 40)
painter.strokePath(path, QPen(Qt.black, 2))
```
接下来,我们可以通过增加棋子图形项来优化代码。目前我们在 `Board` 类中直接绘制了棋子,这样会使代码变得复杂且难以维护。相反,我们可以创建一个 `Piece` 类,用来表示棋子,并将其作为 `Board` 类的子项进行管理。
下面是增加棋子图形项的代码:
```python
class Piece(QGraphicsItem):
def __init__(self, color, parent=None):
super().__init__(parent)
self.color = color
self.setZValue(1)
def boundingRect(self):
return QRectF(-18, -18, 36, 36)
def paint(self, painter, option, widget):
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(Qt.NoPen)
painter.setBrush(QBrush(self.color))
painter.drawEllipse(-15, -15, 30, 30)
```
在 `Piece` 类中,我们继承了 `QGraphicsItem` 类,并实现了 `boundingRect()` 和 `paint()` 方法。`boundingRect()` 方法返回了棋子的边界矩形,用于进行碰撞检测和重新绘制。`paint()` 方法则绘制了棋子的圆形图案。
现在,我们可以在 `Board` 类中管理棋子图形项了。我们可以通过 `addItem()` 和 `removeItem()` 方法来添加或移除棋子。在 `mousePressEvent()` 方法中,我们可以通过 `QGraphicsScene` 的 `itemAt()` 方法获取鼠标点击位置处的图形项,然后判断是否可以放置棋子。如果可以,就添加一个新的棋子图形项。
下面是增加棋子图形项的完整代码:
```python
class Board(QGraphicsObject):
def __init__(self, parent=None):
super().__init__(parent)
self.piece_size = 30
self.grid_size = 40
self.board_size = self.grid_size * 14
self.pieces = []
def boundingRect(self):
return QRectF(0, 0, self.board_size, self.board_size)
def paint(self, painter, option, widget):
painter.setRenderHint(QPainter.Antialiasing)
painter.setPen(QPen(Qt.black, 2))
path = QPainterPath()
# 绘制竖线
for i in range(1, 15):
path.moveTo(i * self.grid_size, self.grid_size)
path.lineTo(i * self.grid_size, self.board_size - self.grid_size)
# 绘制横线
for i in range(1, 15):
path.moveTo(self.grid_size, i * self.grid_size)
path.lineTo(self.board_size - self.grid_size, i * self.grid_size)
painter.strokePath(path, QPen(Qt.black, 2))
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
pos = event.pos()
x = round(pos.x() / self.grid_size) * self.grid_size
y = round(pos.y() / self.grid_size) * self.grid_size
for piece in self.pieces:
if piece.pos() == QPointF(x, y):
return
piece = Piece(Qt.black)
piece.setPos(x, y)
self.addItem(piece)
self.pieces.append(piece)
```
现在,我们已经成功地增加了棋子图形项,并优化了代码。我们可以继续完善游戏逻辑和界面交互,使得游戏更加完整和有趣。