1

私はPysideを使用して、インタラクティブなサブクラス化されたQGraphicsViewを作成しています-いくつかのサブクラス化されたQGraphicsItemsを含みます。それはそれ自身のモジュールでうまく機能し、マウスイベントを受け取ります。

しかし、別のファイルからモジュールとして使用され、別のレイアウトに組み込まれると、マウスイベントがトリガーされません。ただし、.itemChangeは機能しています。マウスイベントを除くすべて。ホバーなどの追跡イベントは使用していません。私はmousePressEventとmouseReleaseEventを使用しています。

「setMouseTracking」の設定に関するC++の応答を見ましたが、これはウィジェット用であり、QGraphicsItemsはウィジェットではなくアイテムとして追加されています。したがって、この関数を呼び出すと、アイテムには存在しないことがわかります。また、それはホバータイプのイベントのようです-私は必要ありません。私は適切にサブクラス化されていると信じており、イベントを親クラスに渡します。冒頭で述べたように、私のコードはスタンドアロンファイルで正常に機能します。

私がするのを忘れたアイデアはありますか?

これがスタンドアロンの動作中のプログラムです:test_subclass_module.pyとして保存

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 > 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() > 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 < index:
                index = sn
                edge = e
            if dn < 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 > index:
                index = sn
                edge = e
            if dn > 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 & 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) > 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 < 0.07 or factor > 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_())

これが親プログラムです-マウスイベントを取得しません:test_toplevel.pyと呼ばれます

# 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_())

完全を期すために。インポートするUIファイルは次のとおりです:test_tabs_ui.py

# -*- 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))
4

2 に答える 2

1

答えがあるので-それは私に私の答えを削除するように合理的に要求します-私はそれを閉じるために私自身の答えで質問に答えなければなりません。3日間待った後...うまくいけば削除できますが、答えがあるのでおそらく削除できません。

于 2012-12-15T03:42:15.900 に答える
0

アプリケーションをダウンロードして試してみたところ、多かれ少なかれ機能していることがわかりました(ただし、test_toplevel.pyではカーソルの位置が間違っています)。

削除しgraph.inhibit_edit = Falseた後もカーソルは正しいままです。

それで、問題はすでに解決されていますか?次に、質問を削除するか、解決済みとして作成すると非常に役立ちます。または、質問を明確にしてください。

于 2012-12-14T23:40:06.013 に答える