PyQt Node 接口 - ItemIsMovable 对象的父对象

PyQt Node interface - Parrent to ItemIsMovable object

因此,我正在使用 PyQt 为我正在处理的项目构建一个基于节点的界面,但在 space 中让属于基础的对象不遵循它时遇到了一些问题。我希望当用户拖动基本节点时,子对象(输入和输出框)跟随它。我有一个可用的可拖动节点,但子对象没有正确跟随。有任何想法吗?

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
This is the base py file for the GUI
"""

import sys
from PyQt4 import QtGui, QtCore
from array import *


"""
Base class for a node. Contains all the initialization, drawing, and containing inputs and outputs
"""

class node():

    width = 100
    height = 100
    color = 1
    x = 90
    y = 60
    inputs=[]
    outputs=[]


    def __init__(self, nWidth, nHeight):
        self.width = nWidth
        self.height = nHeight
        self.iniNodeData()

    """
    This is where inputs and outputs will be created
    """
    def iniNodeData(self):
        for j in range(5):
            this = self
            x = input(this,90, 0+(j*10))
            self.inputs.append(x)



    """Draw the node then the input and output objects"""
    def draw(self, drawObj):
        item = drawObj.addRect(self.x, self.y, self.width, self.height)
        item.setFlag(QtGui.QGraphicsItem.ItemIsMovable)
        for curInput in self.inputs:
            curInput.draw(drawObj) 
        print("(", self.x, ",", self.y, ")")



"""
Nodes will evaluate from the last node to the first node, therefore inputs are evaluted
"""
class input():
    currentConnectedNode = None
    currentConnectedOutput = None
    parentNode = None
    width = 10
    height = 10
    x = 1
    y = 1
    color = 1

    def __init__(self, pnode, posX, posY):

        self.parentNode = pnode
        self.x = posX
        self.y = posY
        self.color = 1


    def draw(self, drawObj):
        item = drawObj.addRect(self.x+self.parentNode.x, self.y+self.parentNode.y, self.width, self.height)


class output():
    parentNode = None


class MainWindow(QtGui.QGraphicsView):

    nodes = []

    def __init__(self):
        super(MainWindow, self).__init__()

        self.initUI()

    def initUI(self):

        for j in range(1):
            x = node(100,100)
            self.nodes.append(x)

        self.setScene(QtGui.QGraphicsScene())    
        self.setWindowTitle('RIS RIB Generator')
        self.setGeometry(800, 600, 800, 850)

        self.initNodes()

        self.show()


    def initNodes(self):

        for curNode in self.nodes:
            curNode.draw(self.scene())



def main():

    app = QtGui.QApplication(sys.argv)
    mainwindow = MainWindow()
    mainwindow.show()
    app.exec_()  


if __name__ == '__main__':
    main()  

好的,一周后我弄明白了。你需要做几件事。

确保标志正确:

    self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
    self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)

一旦设置好,您就可以使用内置的事件处理程序,但这些会覆盖原始事件处理程序。因此,从您的用户定义的内部,您需要从基础 class 调用事件处理程序。示例:

def mousePressEvent(self, e):
    print("Square got mouse press event")
    print("Event came to us accepted: %s"%(e.isAccepted(),))
    QtGui.QGraphicsRectItem.mousePressEvent(self, e)

这是我进步的工作示例。

#!/usr/bin/python
# -*- coding: utf-8 -*-

"""
This is the base py file for the GUI

Todo list
-----------------
- Pop up menu for adding new Nodes
- node connectivity
- create data structure for storing 

"""

import sys
from PyQt4 import QtGui, QtCore
from array import *

"""
Base class for a node. Contains all the inilization, drawing, and containing inputs and outputs
"""
class node(QtGui.QGraphicsRectItem):

    width = 100
    height = 100
    color = 1
    x = 90
    y = 60
    inputs=[]
    outputs=[]
    viewObj = None

    def __init__(self, n_x, n_y, n_width,n_height):
        QtGui.QGraphicsRectItem.__init__(self, n_x, n_y, n_width, n_height)
        self.width = n_width
        self.height = n_height
        self.x = n_x
        self.y = n_y
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
        self.iniNodeData()

    def mousePressEvent(self, e):
        print("Square got mouse press event")
        print("Event came to us accepted: %s"%(e.isAccepted(),))
        QtGui.QGraphicsRectItem.mousePressEvent(self, e)

    def mouseReleaseEvent(self, e):
        print("Square got mouse release event")
        print("Event came to us accepted: %s"%(e.isAccepted(),))
        QtGui.QGraphicsRectItem.mouseReleaseEvent(self, e)

    """
    This is where inputs and outputs will be created based on node type
    """ 
    def iniNodeData(self):
        print('making node data')
        for j in range(5):
            this = self
            x = input(this,0, 0+(j*10))
            self.inputs.append(x)

        for k in range(5):
            this = self
            x = output(this,self.x+self.width, self.y+(k*10))
            self.outputs.append(x)


    def mouseMoveEvent(self, event):
        print('Dragging@')
        QtGui.QGraphicsRectItem.mouseMoveEvent(self, event)


    def mousePressEvent(self, event):

        print('moving!')

"""
Nodes will evaluate from the last node to the first node, therefore inputs are evaluted
"""
class input(QtGui.QGraphicsRectItem):
    currentConnectedNode = None
    currentConnectedOutput = None
    parentNode = None
    width = 10
    height = 10
    x = 1
    y = 1
    color = 1
    drawItem = None

    def __init__(self, pnode, posX, posY):
        self.parentNode = pnode
        self.x = posX
        self.y = posY
        self.color = 1
        QtGui.QGraphicsRectItem.__init__(self, self.x+self.parentNode.x, self.y+self.parentNode.y, self.width, self.height, self.parentNode)



'''
Output value from a node
'''
class output(node):
    parentNode = None
    width = 10
    height = 10
    x = 1
    y = 1

    def __init__(self, pnode, posX, posY):
        self.parentNode = pnode
        self.x = posX
        self.y = posY
        self.color = 1
        QtGui.QGraphicsRectItem.__init__(self, self.x-self.width, self.y, self.width, self.height, self.parentNode)


'''
Check Click events on the scene Object
'''
class Scene(QtGui.QGraphicsScene):


    nodes = []

    def mousePressEvent(self, e):
        print("Scene got mouse press event")
        print("Event came to us accepted: %s"%(e.isAccepted(),))
        QtGui.QGraphicsScene.mousePressEvent(self, e)

    def mouseReleaseEvent(self, e):
        print("Scene got mouse release event")
        print("Event came to us accepted: %s"%(e.isAccepted(),))
        QtGui.QGraphicsScene.mouseReleaseEvent(self, e)

    def dragMoveEvent(self, e):
        print('Scene got drag move event')

    def addNode(self):
        newNode = self.addItem(node(250,250,100,150))
        self.nodes.append(newNode)


'''
Main Window Object
'''

class MainWindowUi(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle('RIS RIB Generator')
        self.scene = Scene(0, 0, 800, 850, self)
        self.view = QtGui.QGraphicsView()
        self.setCentralWidget(self.view)
        self.view.setScene(self.scene)


        exitAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        newNodeAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'New Node', self)
        newNodeAction.setStatusTip('Add a blank node')
        newNodeAction.triggered.connect(self.scene.addNode)


        self.statusBar()
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newNodeAction)
        fileMenu.addAction(exitAction)


'''
Start Point
'''

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    win = MainWindowUi()
    win.show()
    sys.exit(app.exec_())