PySide:容器中 QGraphicsView 的事件过滤器 class
PySide: event-filter for QGraphicsView in container class
我在导入的子小部件和父主要 window 和小部件的类似小部件之间进行通信。但是,当涉及到作为模块和子小部件导入的 QGraphicsScene 小部件时,我感到很困惑。我在下面放了一些简化的文件。因此,QGraphicsView(来自 QGraphicsScene)将是我需要向主 window.
中的其他 QWidget 发出和发出事件信号的实际小部件
如果我将所有 类 都放在一个文件中,它可以工作,但如果我将 类 作为单独的模块,我会收到 "does not have attribute" 错误,特别是在此处的简单版本中QGraphicsScene.viewport
Attribute Error "self.graphicsView.viewport().installEventFilter(self)"
我想复合图形小部件现在实际上是一个 QWidget,我没有为 QGraphicsView 元素初始化导入模块 functions/attributes。事情是,我希望它以这种方式存在,这样我就可以分离不同模块的 GUI 元素和功能。到目前为止我使用的其他方法是从 QObjects 派生的直接 QWidget 到 QWidget 信号,所以工作正常,但我无法使用导入的 QGraphicsScene 到 QWidgets 实现相同的效果,因为它在尝试到达 QGraphicsView 时出错主要window。同样,如果所有 类 都存在于一个大文件中,一切都很好。
有哪位好心人可以指出我的错误吗?我怎样才能将模块脚本分开,使其与单个脚本的行为方式相同?
工作单个脚本:
# QWidgetAll.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
同一个文件作为单独的模块。 qWidgetView.py 属性错误的错误:
# qWidgetView.py
from PySide import QtGui, QtCore
from qGraphicView import GraphicsView
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = WidgetView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
使用导入的 qGraphicView.py 模块:
# qGraphicView.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
您需要过滤 QGraphicsView
的事件,它是 GraphicsView
class 的子窗口小部件,因为您只想在图形视图本身上移动鼠标,而不是整个容器小部件。所以我会建议这样的事情:
qGraphicView.py模块:
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsView.setMouseTracking(True)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
def viewport(self):
return self.graphicsView.viewport()
qWidgetView.py模块:
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
我在导入的子小部件和父主要 window 和小部件的类似小部件之间进行通信。但是,当涉及到作为模块和子小部件导入的 QGraphicsScene 小部件时,我感到很困惑。我在下面放了一些简化的文件。因此,QGraphicsView(来自 QGraphicsScene)将是我需要向主 window.
中的其他 QWidget 发出和发出事件信号的实际小部件如果我将所有 类 都放在一个文件中,它可以工作,但如果我将 类 作为单独的模块,我会收到 "does not have attribute" 错误,特别是在此处的简单版本中QGraphicsScene.viewport
Attribute Error "self.graphicsView.viewport().installEventFilter(self)"
我想复合图形小部件现在实际上是一个 QWidget,我没有为 QGraphicsView 元素初始化导入模块 functions/attributes。事情是,我希望它以这种方式存在,这样我就可以分离不同模块的 GUI 元素和功能。到目前为止我使用的其他方法是从 QObjects 派生的直接 QWidget 到 QWidget 信号,所以工作正常,但我无法使用导入的 QGraphicsScene 到 QWidgets 实现相同的效果,因为它在尝试到达 QGraphicsView 时出错主要window。同样,如果所有 类 都存在于一个大文件中,一切都很好。
有哪位好心人可以指出我的错误吗?我怎样才能将模块脚本分开,使其与单个脚本的行为方式相同?
工作单个脚本:
# QWidgetAll.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
同一个文件作为单独的模块。 qWidgetView.py 属性错误的错误:
# qWidgetView.py
from PySide import QtGui, QtCore
from qGraphicView import GraphicsView
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.setMouseTracking(True)
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.MouseMove and
source is self.graphicsView.viewport()):
pos = event.pos()
self.edit.setText('x: %d, y: %d' % (pos.x(), pos.y()))
return QtGui.QWidget.eventFilter(self, source, event)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = WidgetView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
使用导入的 qGraphicView.py 模块:
# qGraphicView.py
from PySide import QtGui, QtCore
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = GraphicsView()
window.show()
window.resize(200, 100)
sys.exit(app.exec_())
您需要过滤 QGraphicsView
的事件,它是 GraphicsView
class 的子窗口小部件,因为您只想在图形视图本身上移动鼠标,而不是整个容器小部件。所以我会建议这样的事情:
qGraphicView.py模块:
class GraphicsView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = QtGui.QGraphicsView(self)
self.graphicsView.setMouseTracking(True)
self.graphicsLabel = QtGui.QLabel("Graphics View within QWidget")
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.graphicsLabel)
layout.addWidget(self.graphicsView)
def viewport(self):
return self.graphicsView.viewport()
qWidgetView.py模块:
class WidgetView(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.graphicsView = GraphicsView()
self.graphicsView.viewport().installEventFilter(self)
self.edit = QtGui.QLineEdit(self)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.graphicsView)