PyQt报错:'Window'对象无'setScene'属性,如何实现窗口滚动条?
解决AttributeError: 'Window' object has no attribute 'setScene'错误
我来帮你理清这个问题的根源和解决办法:
错误含义解析
这个错误非常明确:你的Window类实例没有setScene这个方法。setScene是PyQt中QGraphicsView控件的专属方法,作用是把QGraphicsScene(绘图场景)绑定到视图上,让视图显示场景里的内容。而你的Window类(从代码片段看应该是继承了QMainWindow或普通QWidget)本身并不具备这个方法,所以直接调用self.setScene(self.scene)就会触发属性错误。
问题根源
你想实现带滚动条的绘图功能,参考的是QGraphicsScene的用法,但混淆了几个PyQt绘图组件的职责:
QGraphicsScene:相当于“画布”,用来承载所有绘图元素(比如形状、图片);QGraphicsView:相当于“窗口/取景器”,用来显示QGraphicsScene的内容,并且默认自带滚动条——当场景内容超过视图的显示范围时,滚动条会自动启用;QMainWindow/QWidget:是主窗口或容器控件,用来组织界面上的各种控件(包括QGraphicsView)。
你的代码错误地直接在主窗口类上调用了属于QGraphicsView的方法,所以报错。
解决方法
有两种常见的修正方式,根据你的需求选择:
方式1:主窗口嵌套QGraphicsView(推荐,更灵活)
让Window作为主窗口,内部创建QGraphicsView控件,再把场景绑定到视图上:
import sys from PyQt4 import QtGui from PyQt4.QtGui import QMainWindow, QWidget, QVBoxLayout, QGraphicsView, QGraphicsScene, QGraphicsRectItem class Window(QMainWindow): def __init__(self): super(Window, self).__init__() self.init_ui() def init_ui(self): # 1. 创建绘图场景 self.scene = QGraphicsScene() # 添加一个测试矩形(超过视图大小会触发滚动条) self.scene.addItem(QGraphicsRectItem(0, 0, 500, 500)) # 2. 创建视图,绑定场景 self.view = QGraphicsView(self.scene) # 视图默认自动显示滚动条,如需自定义可调整: # self.view.setHorizontalScrollBarPolicy(QtGui.Qt.ScrollBarAlwaysOn) # self.view.setVerticalScrollBarPolicy(QtGui.Qt.ScrollBarAlwaysOn) # 3. 把视图放到主窗口的中心区域 central_widget = QWidget() layout = QVBoxLayout(central_widget) layout.addWidget(self.view) self.setCentralWidget(central_widget) self.setWindowTitle("带滚动条的绘图窗口") self.resize(300, 300) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec_())
方式2:让Window继承QGraphicsView
如果你的窗口只需要显示绘图内容,不需要额外的工具栏、菜单等组件,可以直接让Window继承QGraphicsView,这样就能直接调用setScene了:
import sys from PyQt4 import QtGui from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QGraphicsRectItem class Window(QGraphicsView): def __init__(self): super(Window, self).__init__() self.scene = QGraphicsScene() self.setScene(self.scene) # 添加测试元素 self.scene.addItem(QGraphicsRectItem(0, 0, 500, 500)) self.setWindowTitle("直接作为视图的窗口") self.resize(300, 300) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec_())
额外提示
QGraphicsView的滚动条是自动生效的,只要场景的内容尺寸超过视图的显示尺寸,滚动条就会出现;- 如果需要自定义滚动条的显示策略,可以调用
setHorizontalScrollBarPolicy和setVerticalScrollBarPolicy方法,传入Qt.ScrollBarAlwaysOn/Qt.ScrollBarAlwaysOff/Qt.ScrollBarAsNeeded参数。
内容的提问来源于stack exchange,提问作者Aquarius_Girl
相关产品推荐
相关产品推荐

