我有一个 QMainWindows,里面有一个 QGraphicsView,它占据了所有的客户区域。在 View 内,我渲染一些 QGraphicsTextItem 项目。只要我不调整主窗口的大小,一切都会正常。如果我这样做,这些项目将保留在原来的位置,并且不会移动到新的正确位置。基本上我要做的就是具有类似于布局小部件中的行为,如果需要,它会扩展
更新1
更新 2
更新3
使用以下代码,按钮位于客户区的右侧。 944 是从 QGraphicsView 的 Qt Designer 定义的宽度。我对该区域左侧的小部件有相同的代码,从 10 开始 xPos,并在每次添加新按钮时递增它。如果我调整窗口大小,左侧小部件总是会移动到新位置,而右侧小部件则没有相同的行为。为什么?
this->ui.setupUi(this);
qreal xPos = 944 - 10;
QGraphicsTextItem *myButton1 = new QGraphicsTextItem("my text");
myButton1 ->adjustSize();
myButton1 ->setPos(xPos - myButton1 ->textWidth(), 10);
xPos -= myButton1 ->textWidth();
this->m_graphicsScene->addItem(myButton1);
QGraphicsTextItem *myButton2 = new QGraphicsTextItem("my text 2");
myButton2 ->adjustSize();
myButton2 ->setPos(xPos - myButton2->textWidth(), 10);
xPos -= myButton2 ->textWidth();
this->m_graphicsScene->addItem(myButton2);
最佳答案
QGraphicsView 与场景内的 QGraphicsItem 对象没有直接连接。它的唯一目的是在视口(viewport)中可视化场景的一部分,并将用户交互传输到场景。没有布局,但是添加了布局以与 QGraphicsWidget 一起使用(但这是特殊需要的情况)。无论如何,这只是与 View 的平移相关,而不是场景中项目的位置(彼此完全无关)
您最有可能需要做的是子类 QGraphicsView,并在您的 View 中重新实现 resizeEvent:http://qt-project.org/doc/qt-4.8/qgraphicsview.html#resizeEvent
在 resizeEvent 中,您将根据调整大小将 View 平移一定量:http://qt-project.org/doc/qt-4.8/qgraphicsview.html#translate
本质上,您正在自定义 QGraphicsView 中创建自己的布局管理器功能。
更新
我明白你的意思,当 sceneRect 大于 QGraphicsView 时,它将使用滚动条,而不是让你的 View 在调整大小时居中。理想情况下,如果您要创建内容不需要滚动的图形场景类型,则应保留 sceneRect 默认值,或将其设置为视口(viewport)的大小。
否则,这里是一个关于如何使用 resizeEvent 的非常基本的示例。这是 PyQt 中的,但我相信你可以翻译:
class Dialog(QtGui.QDialog):
def __init__(self):
super(Dialog, self).__init__()
self.resize(640,480)
layout = QtGui.QVBoxLayout(self)
self.scene = QtGui.QGraphicsScene(self)
self.scene.setSceneRect(-500,-500,1000,1000)
self.view = GraphicsView(self)
self.view.setScene(self.scene)
layout.addWidget(self.view)
text = self.scene.addText("Foo")
self.view.updateCenter()
class GraphicsView(QtGui.QGraphicsView):
def __init__(self, parent=None):
super(GraphicsView, self).__init__(parent)
self._center = None
def resizeEvent(self, event):
super(GraphicsView, self).resizeEvent(event)
if self._center:
self.centerOn(self._center)
def updateCenter(self):
center = self.geometry().center()
self._center = self.mapToScene(center)
当您调用updateCenter()
时,它会保存您感兴趣的场景点。然后,每次调整 View 大小时,它都会回到该场景点的中心。
更新 2:图片发布和更新后
如果您确实需要在 QGraphicsScene 中使用这种带有布局的正常 QWidget 行为,那么您应该考虑 QGraphicsWidgets,它确实支持布局。然后,您可以制作一个大型根“ Canvas ”小部件,并在布局内部将其他所有内容都设为该小部件的子级。那么您只需要担心保持根小部件的大小正确即可。然后,您将能够使用上面相同的示例来管理根小部件的大小和位置。
请参阅此问题以获取更多详细信息,因为它与想要将 QGraphicsItem 集成到布局中的人的情况相同:
QGraphicsWidget vs. QGraphicsLayoutItem
关于qt4 - 调整 QGraphicsView 大小不会移动小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10770255/