bjlaocao 发表于 2024-11-20 08:59:03

PySide6的图形显示问题

我在一个QWidget中设置了QVBoxLayout,然后放入QGraphicsView和QGraphicsScene,之后,在Scene中画图的时候,无论坐标如何设置,layout都将图形自动居中摆放,这是啥问题?这种情况下,如何才能在指定的坐标处自由摆放自己创建的图形?我的代码如下:
from PySide6.QtWidgets import QWidget, QPushButton, QGraphicsView, QGraphicsScene, QGraphicsEllipseItem,QVBoxLayout
from PySide6.QtGui import QPen, QBrush, QColor,QPainter
from PySide6.QtCore import Qt, QRectF, QPointF

class GraphicsView(QGraphicsView):
    def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.setRenderHints(QPainter.Antialiasing)# 开启抗锯齿
       # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
      #self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

class MyWidget(QWidget):
    def __init__(self):
      super().__init__()
      self.init_ui()

    def init_ui(self):
      # 设置主窗口的大小
      self.resize(420, 370)

      self.layout = QVBoxLayout()

      # 创建 QGraphicsView 和 QGraphicsScene
      self.scene = QGraphicsScene()
      self.view = GraphicsView(self.scene, self)
      self.view.setGeometry(10, 10, 400, 300)# 设置视图的位置和大小

      # 将 QGraphicsView 添加到布局中
      self.layout.addWidget(self.view)

      # 创建按钮
      self.add_button = QPushButton("Add Circle", self)
      self.add_button.setGeometry(10, 320, 100, 30)# 设置按钮的位置和大小

      self.remove_button = QPushButton("Remove Circle", self)
      self.remove_button.setGeometry(120, 320, 120, 30)# 设置按钮的位置和大小

      # 连接按钮点击事件
      self.add_button.clicked.connect(self.add_circle)
      self.remove_button.clicked.connect(self.remove_circle)

      # 初始化圆圈变量
      self.circle = None

    def add_circle(self):

      rect = QRectF(100, 40, 10, 10)
      self.circle = self.scene.addEllipse(rect, QPen(Qt.black))
      
      
    def remove_circle(self):
      # 删除圆圈
      if self.circle is not None:
            self.scene.removeItem(self.circle)
            self.circle = None

if __name__ == "__main__":
    from PySide6.QtWidgets import QApplication
    app = QApplication([])
    main_window = MyWidget()
    main_window.show()
    app.exec()

FishC 发表于 2024-11-20 08:59:15

你好!在你的代码中,QGraphicsView会自动居中显示QGraphicsScene中的内容,这是因为QGraphicsView默认会根据场景的边界来调整视图的中心。

要在指定的坐标处自由摆放图形,你可以调整视图的变换矩阵,或者直接设置视图的中心点。以下是一些可能的解决方案:

1. **禁用自动居中**:可以通过设置视图的变换矩阵来禁用自动居中。

2. **设置视图的中心点**:使用`centerOn`方法来设置视图的中心点。

以下是如何实现的示例:

# 在add_circle方法中添加以下代码
self.view.setSceneRect(self.scene.itemsBoundingRect())# 设置场景矩形
self.view.centerOn(0, 0)# 将视图中心设置为场景的原点

这样,视图就不会自动居中到场景的内容上,而是根据你指定的坐标来显示图形。希望这能解决你的问题!如果有其他问题,请随时问我。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

bjlaocao 发表于 2024-11-20 09:09:18

尝试过了,不解决问题,还是自动居中显示

FishC 发表于 2024-11-20 09:10:28

bjlaocao 发表于 2024-11-20 09:09
尝试过了,不解决问题,还是自动居中显示

如果上述方法没有解决问题,你可以尝试以下步骤来确保图形可以按指定坐标显示:

1. **禁用视图的自动调整功能**:

   在`GraphicsView`初始化时,禁用缩放和调整功能:

self.setTransformationAnchor(QGraphicsView.NoAnchor)
self.setResizeAnchor(QGraphicsView.NoAnchor)

2. **设置场景矩形**:

   直接在初始化时指定场景的矩形大小,以明确场景的可视区域:

self.scene.setSceneRect(0, 0, 400, 300)

3. **关闭反锯齿(可选项但建议尝试)**:

   有时反锯齿可能会影响显示效果,尝试关闭它:

# self.setRenderHints(QPainter.Antialiasing)

这是更新后的代码示例:

class GraphicsView(QGraphicsView):
    def __init__(self, *args, **kwargs):
      super().__init__(*args, **kwargs)
      self.setTransformationAnchor(QGraphicsView.NoAnchor)
      self.setResizeAnchor(QGraphicsView.NoAnchor)
      self.setRenderHints(QPainter.Antialiasing)# 尝试保持抗锯齿,但可以注释掉
      # self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
      # self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

class MyWidget(QWidget):
    def init_ui(self):
      # ...
      self.scene.setSceneRect(0, 0, 400, 300)# 设置场景矩形
      # ...

    def add_circle(self):
      rect = QRectF(100, 40, 10, 10)
      self.circle = self.scene.addEllipse(rect, QPen(Qt.black))

请确保在设置`sceneRect`之后再添加图形。通过以上调整,应该可以控制图形按指定坐标显示。如果问题仍然存在,请给我更多细节,我会进一步协助你。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: PySide6的图形显示问题