Note that there are some explanatory texts on larger screens.

plurals
  1. POsubclassed QGraphicsItem not getting mouse events when used as module
    primarykey
    data
    text
    <p>I'm using Pyside to create an interactive subclassed QGraphicsView - containing some subclassed QGraphicsItems. It works well in its own module and receives mouse events. </p> <p>But when used as a module from another file, and incorporated into another Layout - my mouse events are not being triggered. However .itemChange is working. Everything except the mouse events. I am not using tracking events such as hover. I am using mousePressEvent and mouseReleaseEvent.</p> <p>I have seen c++ responses about setting "setMouseTracking" but this is for widgets and my QGraphicsItems have been added as items not widgets. So when I call this funcion it tells me it doesn't exist for items. Also that seems to be for hover type of events - which I am not needing. I believe I am subclassing properly and I pass on the events to the parent class. As I said at the start - my code works fine in a standalone file.</p> <p>Any ideas what I've forgotten to do ?</p> <p>Here is the standalone - working program: Save as test_subclass_module.py</p> <pre><code>import sys import weakref import math from PySide import QtCore, QtGui ### class Edge(QtGui.QGraphicsItem): Type = QtGui.QGraphicsItem.UserType + 2 def __init__(self, sourceNode, destNode): QtGui.QGraphicsItem.__init__(self) # self.sourcePoint = QtCore.QPointF() self.destPoint = QtCore.QPointF() self.setAcceptedMouseButtons(QtCore.Qt.NoButton) self.source = weakref.ref(sourceNode) self.dest = weakref.ref(destNode) self.source().addEdge(self) self.dest().addEdge(self) self.set_index() self.adjust() def type(self): return Edge.Type def sourceNode(self): return self.source() def setSourceNode(self, node): self.source = weakref.ref(node) self.adjust() def destNode(self): return self.dest() def setDestNode(self, node): self.dest = weakref.ref(node) self.adjust() def set_index(self): self.setToolTip(self.source().label) def adjust(self): # do we have a line to draw ? if self.source() and self.dest(): line = QtCore.QLineF(self.mapFromItem(self.source(), 0, 0), self.mapFromItem(self.dest(), 0, 0)) length = line.length() if length &gt; 20: edgeOffset = QtCore.QPointF((line.dx() * 10) / length, (line.dy() * 10) / length) self.prepareGeometryChange() self.sourcePoint = line.p1() + edgeOffset self.destPoint = line.p2() - edgeOffset else: # want to make sure line not drawn self.prepareGeometryChange() self.sourcePoint = self.destPoint def boundingRect(self): # do we have a line to draw ? if not self.source() or not self.dest(): return QtCore.QRectF() else: extra = 1 return QtCore.QRectF(self.sourcePoint, QtCore.QSizeF(self.destPoint.x() - self.sourcePoint.x(), self.destPoint.y() - self.sourcePoint.y())).normalized().adjusted(-extra, -extra, extra, extra) def paint(self, painter, option, widget): if self.source() and self.dest(): # Draw the line itself. line = QtCore.QLineF(self.sourcePoint, self.destPoint) if line.length() &gt; 0.0: painter.setPen(QtGui.QPen(QtCore.Qt.black, 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)) painter.drawLine(line) ### class Node(QtGui.QGraphicsItem): Type = QtGui.QGraphicsItem.UserType + 1 def __init__(self, graphWidget, time, temp, pos): QtGui.QGraphicsItem.__init__(self) self.graph = weakref.ref(graphWidget) self.edgeList = [] self.set_index(pos) self.newPos = QtCore.QPointF() self.setFlag(QtGui.QGraphicsItem.ItemIsMovable) self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges) self.setCacheMode(self.DeviceCoordinateCache) self.setZValue(-1) # self.temp = temp self.time = time x,y = self.map_temptime_to_pos() self.setPos(x,y) self.marker = False def type(self): return Node.Type def addEdge(self, edge): self.edgeList.append(weakref.ref(edge)) def set_index(self, index): self.index = index self.label = "Step %d" % index self.setToolTip(self.label) def get_prev_edge(self): index = 1000 edge = False for e in self.edgeList: sn = e().source().index dn = e().dest().index if sn &lt; index: index = sn edge = e if dn &lt; index: index = dn edge = e return edge def get_next_edge(self): index = -1 edge = False for e in self.edgeList: sn = e().source().index dn = e().dest().index if sn &gt; index: index = sn edge = e if dn &gt; index: index = dn edge = e return edge def map_temptime_to_pos(self): x = self.time * self.graph().graph_width_ratio y = self.graph().size[3] - self.temp * self.graph().graph_height_ratio return (x,y) def boundingRect(self): adjust = 2.0 return QtCore.QRectF(-10 - adjust, -10 - adjust, 22 + adjust, 23 + adjust) def paint(self, painter, option, widget): painter.drawLine(QtCore.QLineF(6,-40,6,-2)) painter.setPen(QtCore.Qt.NoPen) painter.setBrush(QtCore.Qt.lightGray) painter.drawEllipse(-10, -10, 20, 20) gradient = QtGui.QRadialGradient(0, 0, 22) if option.state &amp; QtGui.QStyle.State_Sunken: # selected gradient.setColorAt(0, QtGui.QColor(QtCore.Qt.darkGreen).lighter(120)) else: gradient.setColorAt(1, QtCore.Qt.blue) painter.setBrush(QtGui.QBrush(gradient)) painter.setPen(QtGui.QPen(QtCore.Qt.black, 0)) painter.drawEllipse(-6, -6, 12, 12) def itemChange(self, change, value): if change == QtGui.QGraphicsItem.ItemPositionChange: for edge in self.edgeList: edge().adjust() return QtGui.QGraphicsItem.itemChange(self, change, value) def mousePressEvent(self, event): if not self.graph().inhibit_edit: self.update() print "Node pressed" QtGui.QGraphicsItem.mousePressEvent(self, event) def mouseReleaseEvent(self, event): if not self.graph().inhibit_edit: self.update() print "Node released" # QtGui.QGraphicsItem.mouseReleaseEvent(self, event) ### class GraphWidget(QtGui.QGraphicsView): def __init__(self): QtGui.QGraphicsView.__init__(self) self.size = (-30, 30, 600, 400) # scene = QtGui.QGraphicsScene(self) scene.setItemIndexMethod(QtGui.QGraphicsScene.NoIndex) scene.setSceneRect(self.size[0],self.size[1],self.size[2],self.size[3]) self.setScene(scene) self.setCacheMode(QtGui.QGraphicsView.CacheBackground) self.setRenderHint(QtGui.QPainter.Antialiasing) self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QtGui.QGraphicsView.AnchorViewCenter) # self.maxtemp = 300 self.maxtime = 160 self.nodecount = 0 self.calc_upper_limits() # self.scale(0.8, 0.8) self.setMinimumSize(600, 400) self.setWindowTitle(self.tr("Elastic Nodes")) self.inhibit_edit = False def calc_upper_limits(self): self.toptemp = (self.maxtemp / 100 + 1) * 100 self.toptime = (int(self.maxtime) / 30 + 1) * 30 self.graph_width_ratio = float(self.size[2]) /self.toptime self.graph_height_ratio = float(self.size[3]) / self.toptemp def add_node(self, time, temp, marker=False, pos=-1): self.nodecount += 1 scene = self.scene() # Insert Node into scene node = Node(self, time, temp, self.nodecount) scene.addItem(node) # Insert new edges nodes = self.get_ordered_nodes() if len(nodes) &gt; 1: e = Edge(nodes[-2], node) scene.addItem(e) # cleanup edge tooltips for n in self.get_ordered_nodes(): edges = n.edgeList for e in edges: e().set_index() def get_ordered_nodes(self): nodes = [item for item in self.scene().items() if isinstance(item, Node)] nodes.sort(key=lambda n: n.index) return nodes def keyPressEvent(self, event): key = event.key() if key == QtCore.Qt.Key_Plus: self.scaleView(1.2) elif key == QtCore.Qt.Key_Minus: self.scaleView(1 / 1.2) else: QtGui.QGraphicsView.keyPressEvent(self, event) def mousePressEvent(self, event): print "GraphWidget mouse" QtGui.QGraphicsView.mousePressEvent(self, event) def wheelEvent(self, event): self.scaleView(math.pow(2.0, -event.delta() / 240.0)) def scaleView(self, scaleFactor): factor = self.matrix().scale(scaleFactor, scaleFactor).mapRect(QtCore.QRectF(0, 0, 1, 1)).width() if factor &lt; 0.07 or factor &gt; 100: return self.scale(scaleFactor, scaleFactor) def drawBackground(self, painter, rect): sceneRect = self.sceneRect() if __name__ == "__main__": app = QtGui.QApplication(sys.argv) widget = GraphWidget() widget.add_node(0, 25) widget.add_node(30, 100) widget.add_node(60, 200) widget.show() sys.exit(app.exec_()) </code></pre> <p>Here is the parent program - which does not get the mouse events: Called test_toplevel.py</p> <pre><code># import user interface etc from PySide import QtCore, QtGui from test_tabs_ui import Ui_Form from test_subclass_module import * import sys Programs = {"Gen13": {"steps": [[0, 0, 0], [0, 30, 30], [0, 60, 60], [0, 77, 77]] }} ###----------------------------------------------------------- ### The dialog class Nusku_tab_Add_kiln(QtGui.QWidget): """ Create dialog to add/delete kilns from controlled kilns """ def __init__(self, parent=None): # Get the UI loaded super(Nusku_tab_Add_kiln, self).__init__(parent) self.ui = Ui_Form() self.ui.setupUi(self) self.current = Programs['Gen13'] # draw program in graphicsView # swap out the standin self.ui.graphLayout.removeWidget(self.ui.graphicsView) self.ui.graphicsView.setParent(None) self.ui.graphicsView.deleteLater() self.graph = GraphWidget() self.ui.graphLayout.addWidget(self.graph) self.draw_graph() def choose_program(self): pass def draw_graph(self): graph = self.graph graph.inhibit_edit = True steps = self.current['steps'] for s in steps: print s graph.add_node(s[1],s[2]) ###------------------------------------------------ if __name__ == '__main__': app = QtGui.QApplication(sys.argv) prog = Nusku_tab_Add_kiln() prog.show() sys.exit(app.exec_()) </code></pre> <p>For sake of completeness. Here is the ui file it imports: test_tabs_ui.py</p> <pre><code># -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'test_tabs.ui' # # Created: Wed Dec 05 15:20:02 2012 # by: pyside-uic 0.2.14 running on PySide 1.1.1 # # WARNING! All changes made in this file will be lost! from PySide import QtCore, QtGui class Ui_Form(object): def setupUi(self, Form): Form.setObjectName("Form") Form.resize(595, 540) self.verticalLayout = QtGui.QVBoxLayout(Form) self.verticalLayout.setObjectName("verticalLayout") self.tabWidget = QtGui.QTabWidget(Form) self.tabWidget.setObjectName("tabWidget") self.Tab_Program = QtGui.QWidget() self.Tab_Program.setObjectName("Tab_Program") self.verticalLayout_2 = QtGui.QVBoxLayout(self.Tab_Program) self.verticalLayout_2.setObjectName("verticalLayout_2") self.frame_graph_status = QtGui.QFrame(self.Tab_Program) self.frame_graph_status.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_graph_status.setFrameShadow(QtGui.QFrame.Raised) self.frame_graph_status.setObjectName("frame_graph_status") self.horizontalLayout_7 = QtGui.QHBoxLayout(self.frame_graph_status) self.horizontalLayout_7.setSpacing(0) self.horizontalLayout_7.setContentsMargins(0, 0, 0, 0) self.horizontalLayout_7.setObjectName("horizontalLayout_7") self.frame_program = QtGui.QFrame(self.frame_graph_status) self.frame_program.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_program.setFrameShadow(QtGui.QFrame.Raised) self.frame_program.setObjectName("frame_program") self.graphLayout = QtGui.QVBoxLayout(self.frame_program) self.graphLayout.setContentsMargins(-1, 0, -1, 0) self.graphLayout.setObjectName("graphLayout") self.graphicsView = QtGui.QGraphicsView(self.frame_program) self.graphicsView.setObjectName("graphicsView") self.graphLayout.addWidget(self.graphicsView) self.horizontalLayout_7.addWidget(self.frame_program) self.verticalLayout_2.addWidget(self.frame_graph_status) self.widget_prog = QtGui.QWidget(self.Tab_Program) self.widget_prog.setObjectName("widget_prog") self.prog_layout = QtGui.QGridLayout(self.widget_prog) self.prog_layout.setContentsMargins(4, 4, 4, 4) self.prog_layout.setSpacing(0) self.prog_layout.setContentsMargins(0, 0, 0, 0) self.prog_layout.setObjectName("prog_layout") self.verticalLayout_2.addWidget(self.widget_prog) self.tabWidget.addTab(self.Tab_Program, "") self.Tab_alarms = QtGui.QWidget() self.Tab_alarms.setObjectName("Tab_alarms") self.alarms_tab_layout = QtGui.QVBoxLayout(self.Tab_alarms) self.alarms_tab_layout.setObjectName("alarms_tab_layout") self.tabWidget.addTab(self.Tab_alarms, "") self.Tab_settings = QtGui.QWidget() self.Tab_settings.setObjectName("Tab_settings") self.settings_tab_layout = QtGui.QVBoxLayout(self.Tab_settings) self.settings_tab_layout.setObjectName("settings_tab_layout") self.tabWidget.addTab(self.Tab_settings, "") self.Tab_pid = QtGui.QWidget() self.Tab_pid.setObjectName("Tab_pid") self.verticalLayout_8 = QtGui.QVBoxLayout(self.Tab_pid) self.verticalLayout_8.setSpacing(0) self.verticalLayout_8.setContentsMargins(0, 0, 0, 0) self.verticalLayout_8.setObjectName("verticalLayout_8") self.scrollArea_2 = QtGui.QScrollArea(self.Tab_pid) self.scrollArea_2.setWidgetResizable(True) self.scrollArea_2.setObjectName("scrollArea_2") self.scrollAreaWidgetContents_2 = QtGui.QWidget() self.scrollAreaWidgetContents_2.setGeometry(QtCore.QRect(0, 0, 569, 494)) self.scrollAreaWidgetContents_2.setObjectName("scrollAreaWidgetContents_2") self.PID_tab_layout = QtGui.QVBoxLayout(self.scrollAreaWidgetContents_2) self.PID_tab_layout.setSpacing(0) self.PID_tab_layout.setContentsMargins(0, 0, 0, 0) self.PID_tab_layout.setObjectName("PID_tab_layout") self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) self.verticalLayout_8.addWidget(self.scrollArea_2) self.tabWidget.addTab(self.Tab_pid, "") self.verticalLayout.addWidget(self.tabWidget) self.retranslateUi(Form) self.tabWidget.setCurrentIndex(0) QtCore.QMetaObject.connectSlotsByName(Form) Form.setTabOrder(self.tabWidget, self.graphicsView) Form.setTabOrder(self.graphicsView, self.scrollArea_2) def retranslateUi(self, Form): Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8)) self.graphicsView.setToolTip(QtGui.QApplication.translate("Form", "decimal point", None, QtGui.QApplication.UnicodeUTF8)) self.graphicsView.setStatusTip(QtGui.QApplication.translate("Form", "Accuracy can be increased at lower temperatures", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Tab_Program), QtGui.QApplication.translate("Form", "Program", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Tab_alarms), QtGui.QApplication.translate("Form", "Alarms", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Tab_settings), QtGui.QApplication.translate("Form", "Settings", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.Tab_pid), QtGui.QApplication.translate("Form", "PID", None, QtGui.QApplication.UnicodeUTF8)) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload