PyQt4主窗口滚动条与嵌入场景交互异常问题求助
Hey there! I’ve run into this exact issue before—when you resize your main window, the scene seems to shift along with the scrollbars and disappear off-screen. Let’s break down why this happens and how to fix it.
What’s Causing This?
Most of the time, this problem stems from two missing configurations:
- Your
QGraphicsViewdoesn’t have a clear anchor point to stick to when resizing, so it shifts the scene unexpectedly. - The
QGraphicsScenedoesn’t have a defined bounding rectangle, so the view can’t calculate the correct scrollbar ranges or scene positioning.
Step-by-Step Fix
Here’s how to adjust your code to resolve the issue:
1. Set the Scene’s Bounding Rectangle
Tell the scene exactly how big its content is using setSceneRect(). This gives the view a clear boundary to work with, so scrollbars and scene positioning behave predictably.
2. Configure the View’s Resize Anchor
Set an anchor point for the view so when the window resizes, the scene stays anchored to a consistent spot (like the center of the view or the mouse position).
Modified Example Code
I’ve filled out your simplified code with these fixes:
import sys, os from pyface.qt import QtGui, QtCore os.environ['ETS_TOOLKIT'] = 'qt4' from traits.api import HasTraits, Instance, on_trait_change class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.view = QtGui.QGraphicsView(self) self.setCentralWidget(self.view) # Create test scene with sample items self.scene = QtGui.QGraphicsScene() self.scene.addRect(0, 0, 200, 200, QtGui.QPen(QtCore.Qt.red)) self.scene.addEllipse(300, 300, 100, 100, QtGui.QPen(QtCore.Qt.blue)) # Critical: Define the scene's bounding rectangle to match its content self.scene.setSceneRect(self.scene.itemsBoundingRect()) # Set resize anchor to keep scene centered when window resizes # You can also use AnchorUnderMouse if you want to stick to the mouse position self.view.setResizeAnchor(QtGui.QGraphicsView.AnchorViewCenter) self.view.setScene(self.scene) class App(HasTraits): window = Instance(QtGui.QMainWindow) def __init__(self, **kwargs): super(App, self).__init__(**kwargs) self.window = MainWindow() @on_trait_change('window.closeEvent') def _on_window_closed(self, event): self.window.close() event.accept() if __name__ == '__main__': app = App() app.window.show() sys.exit(QtGui.QApplication.instance().exec_())
Why This Works
setSceneRect(self.scene.itemsBoundingRect()): This automatically calculates the smallest rectangle that fits all items in your scene, so the view knows exactly where the scene starts and ends. No more guesswork on scrollbar ranges or scene positioning.setResizeAnchor(...): This locks the scene’s position relative to the view during resizing.AnchorViewCenterkeeps the scene centered, whileAnchorUnderMousekeeps the item under your mouse in view—pick whichever fits your use case.
Other Things to Check
- Make sure you’re not manually adjusting the viewport’s position or size anywhere in your code. Let Qt handle viewport management automatically.
- If you’re using layouts, ensure the
QGraphicsViewis properly added to the layout (instead of being placed with fixed coordinates) so it resizes with the window correctly.
内容的提问来源于stack exchange,提问作者ees

