You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt4主窗口滚动条与嵌入场景交互异常问题求助

Fixing PyQt4 QGraphicsScene Drifting with Scrollbars After Window Resize

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:

  1. Your QGraphicsView doesn’t have a clear anchor point to stick to when resizing, so it shifts the scene unexpectedly.
  2. The QGraphicsScene doesn’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. AnchorViewCenter keeps the scene centered, while AnchorUnderMouse keeps 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 QGraphicsView is properly added to the layout (instead of being placed with fixed coordinates) so it resizes with the window correctly.

内容的提问来源于stack exchange,提问作者ees

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:15:57