[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [PyQt] QGraphicsObject setGeometry with QGraphicsRectItem setRect
From:       Harsha Rani <ranishashi () gmail ! com>
Date:       2017-06-23 23:10:55
Message-ID: CAB=SDtSJyNcHYterTz8N_vhptV6usvWpPc2DjQva6MzkcUtXxA () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


I am having problem in setting setGeomtry of QGraphicsObject with setRect
of QGraphicsRectItem to the same position. (QGraphicsRectItem inturn
inherited from QGraphicsObject)

I have many QGraphicsItems types, so I have a single QGObj
(QGraphicsObject) class that can share a QObject class for signal and slot.

I have small snippet below, may be my implementation is wrong or what I am
trying to archive may not be possible or setting the parameter is/are wrong.

The flow of my work is
widget -> class *OuterItem* (parent is "widget") ->
class *innerItem* (parent is "OuterItem") ->
class *childItem* (parent is "innerItem")

1. *OuterItem* is grey color rect
2.* innerItem *is blue color rect

to setRect for "*OuterItem*" is calculated using
outerItem.childrenBoundingRect()

to setRect/setGeometry  for "*innerItem*" class is
innerItem.childboundaryRect()
I have a question:

1. Blue rectangle box should start drawing the rectangle from "*topchild*",
but
one can see that there is displayment in the topleft corner,
but  bottonleft corner get it right.

This is b'cos *innerItem*.childrenBoundingRect() would also contain
QGraphicsRectitem of GrpItem,
this is can be overcome by re-calculationg manually.

Assume I got this (in the file line 300) and when I tried to set setGeomtry
and setRect then there is mismatch, after this mismatch, if I click on to
the *innerItem *(bluecolor) one can see that object is not selected (It
should display as __main__innerItem

And I need to keep this object *innerItem* inherited from QGObj (which is
inherited from QGraphicsObject)

What I am doing wrong in setting the QGraphicsRectItem (setRect) and
QGraphicsObject (setGeomtry).

[Attachment #5 (text/html)]

<div dir="ltr"><div>I am having problem in setting setGeomtry of QGraphicsObject with \
 setRect of QGraphicsRectItem to the same position. (QGraphicsRectItem 
inturn inherited from QGraphicsObject)<br><br>I have many QGraphicsItems
 types, so I have a single QGObj (QGraphicsObject) class that can share a
 QObject class for signal and slot.<br><br>I have small snippet below, may be my \
implementation is wrong or what I am trying  to archive may not be possible or \
setting the parameter is/are wrong.<br><br>The  flow of my work is <br>widget -&gt; \
                class <b>OuterItem</b> (parent is &quot;widget&quot;) 
-&gt;<br>class <b>innerItem</b> (parent is &quot;OuterItem&quot;) -&gt; <br>class \
<b>childItem</b> (parent is  &quot;innerItem&quot;)<br><br>1. <b>OuterItem</b> is \
grey color rect<br>2.<b> innerItem </b>is blue color rect<br><br>to setRect for \
&quot;<b>OuterItem</b>&quot; is calculated using \
outerItem.childrenBoundingRect()<br><br>to setRect/setGeometry   for \
&quot;<b>innerItem</b>&quot; class is \
innerItem.childboundaryRect()<br></div><div><div>I have a \
question:<br><br></div><div>1. Blue rectangle box should start drawing the rectangle \
from &quot;<b>topchild</b>&quot;, but<br>one can see that there is displayment in the \
topleft corner, <br>but   bottonleft corner get it right.<br><br></div><div>This is \
b&#39;cos <b>innerItem</b>.childrenBoundingRect() would also contain \
QGraphicsRectitem of GrpItem,<br>this is can be overcome by re-calculationg \
manually.<br></div><div><br>Assume I got this (in the file line 300) and when I tried \
to set setGeomtry and setRect then there is mismatch, after this mismatch, if I click \
on to the <b>innerItem </b>(bluecolor) one can see that object is not selected (It \
should display as __main__innerItem<br><br></div><div>And I need to keep this object \
<b>innerItem</b> inherited from QGObj (which is inherited from \
QGraphicsObject)</div><br>What I am doing wrong in setting the QGraphicsRectItem \
(setRect) and QGraphicsObject (setGeomtry).<br></div><div><div><br></div></div></div>


["boundary.py" (text/x-python)]

## This is what I am trying below, 
# outerBoundary --parent --Widget, 
# Inner Boundary --parent-- OuterBoundary
# Child1 --- parent -- innerBoundary

#  _ _ _ _ OuterBoundary _ _ _ _ _ _
# |                                 |
# |  _ _ _ Inner Boundary _ _ _     |
# | |  Child1                  |    |
# | |                          |    |
# | |                 child2   |    |
# | |_ _ _ _ _ _ _ _ _ _ _ _  _|    |
# |_ _ _ _ OuterBoundary _ _ _      |
import sys
from PyQt4 import QtGui, QtCore, Qt, QtSvg
from PyQt4.QtGui import QColor, QImage, QPen

class GraphicalView(QtGui.QGraphicsView):

    def __init__(self, parent):
        QtGui.QGraphicsView.__init__(self,parent)
        self.setScene(parent)
        self.connectionSign          = None
        self.connectionSource        = None
        self.connector               = None
        self.connectionSignImagePath = "../gui/icons/connection.png"
        self.connectionSignImage     = QImage(self.connectionSignImagePath)
        self.sceneContainerPt = parent
        self.setRenderHints(QtGui.QPainter.Antialiasing)
        self.connectorlist = {"plot": None ,"clone": None,"move": None,"delete": \
None}  self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
    
    def mousePressEvent(self, event): 
        self.clickPosition  = self.mapToScene(event.pos())
        print "---------- Start ----------"
        print self.items(event.pos())
        for item in self.items(event.pos()):
            if hasattr(item, "name"):
                if item.name == "ITEM":
                    #self.showConnector(item)
                    pass

    def mouseMoveEvent(self,event):
        pass

    def mouseReleaseEvent(self, event):
        
        self.clickPosition  = self.mapToScene(event.pos())
        for item in self.items(event.pos()):
            if hasattr(item, "name"):
                if item.name == "ITEM":
                    print item
                    break;
        return 
    

    def showConnector(self, item):
        #print " showConnector"
        self.removeConnector()
        self.connectionSource = item
        rectangle = item.boundingRect()

        for l in self.connectorlist.keys():
            self.xDisp = 0
            self.yDisp = 0
            self.connectionSign = None
            print " showConnector ",item,
            if isinstance(item ,InnerItem):
                if l == "clone":
                    self.connectionSign = QtSvg.QGraphicsSvgItem('icons/clone.svg')
                    self.connectionSign.setData(0, QtCore.QVariant("clone"))
                    self.connectionSign.setParent(self.connectionSource)
                    self.connectionSign.setScale(
                    (0.2 * rectangle.height()) / \
self.connectionSign.boundingRect().height())  position = \
item.mapToParent(rectangle.bottomLeft())  self.xDisp = 15
                    self.yDisp = 2
                    self.connectionSign.setZValue(1)
                    self.connectionSign.setToolTip("Click and drag to clone the \
object")  self.connectorlist["clone"] = self.connectionSign

                if l == "plot":
                    self.connectionSign = QtSvg.QGraphicsSvgItem('icons/plot.svg')
                    self.connectionSign.setData(0, QtCore.QVariant("plot"))
                    self.connectionSign.setParent(self.connectionSource)
                    self.connectionSign.setScale(
                        (0.2 * rectangle.height()) / \
self.connectionSign.boundingRect().height()  )
                    position = item.mapToParent(rectangle.bottomRight())
                    self.connectionSign.setZValue(1)
                    self.connectionSign.setToolTip("plot the object")
                    self.connectorlist["plot"] = self.connectionSign

                if l == "move":
                    self.connectionSign = QtSvg.QGraphicsSvgItem('icons/move.svg')
                    self.connectionSign.setData(0, QtCore.QVariant("move"))
                    self.connectionSign.setParent(self.connectionSource)
                    self.connectionSign.setToolTip("Drag to move.")
                    self.connectionSign.setScale(
                            (0.2 * rectangle.height()) / \
self.connectionSign.boundingRect().height()  )
                    position = item.mapToParent(rectangle.topLeft())
                    self.xDisp = 15
                    self.yDisp = 2
                    self.connectionSign.setZValue(1)
                    self.connectorlist["move"] = self.connectionSign
                elif l == "delete":
                    self.connectionSign = QtSvg.QGraphicsSvgItem('icons/delete.svg')
                    self.connectionSign.setParent(self.connectionSource)
                    self.connectionSign.setData(0, QtCore.QVariant("delete"))
                    self.connectionSign.setScale(
                            (0.2 * rectangle.height()) / \
self.connectionSign.boundingRect().height()  )
                    position = item.mapToParent(rectangle.topRight())
                    self.connectionSign.setZValue(1)
                    self.connectionSign.setToolTip("Delete the object")
                    self.connectorlist["delete"] = self.connectionSign

            
            if self.connectionSign != None:
                self.connectionSign.setFlag(QtGui.QGraphicsItem.ItemIsSelectable,True)
  self.connectionSign.setParentItem(item.parentItem())
                self.connectionSign.setPos(0.0,0.0)
                self.connectionSign.moveBy( position.x()-self.xDisp
                                          , position.y() +self.yDisp - \
rectangle.height() / 2.0  )
    def removeConnector(self):
        try:
            for l,k in self.connectorlist.items():
                if k is not None:
                    self.sceneContainerPt.removeItem(k)
                    self.connectorlist[l] = None
        except:
            #print("Exception received!")
            pass

class GraphicalScene(QtGui.QGraphicsScene):
    def __init__(self, parent):
        QtGui.QGraphicsScene.__init__(self,parent)

class QGObj(QtGui.QGraphicsWidget):
    """Base class for display elemenets in kinetics layout"""
    defaultFontName = "Helvetica"
    defaultFontSize = 10
    name = "ITEM"
    def __init__(self, name, parent=None):
        QtGui.QGraphicsObject.__init__(self,parent)
        self.mobj = name
        self.gobj = None
        self.pressed = False
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable,True)
        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
        self.setAcceptHoverEvents(True)
        
    def getParentGraphicsObject(self):
        return self.parentItem()

    def paint(self, painter=None, option=None, widget = None):
        # painter.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.red, 5,Qt.Qt.SolidLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin)))  # painter.drawRect(self.boundingRect()) 
        # print "\t \t @KDI paint ",self.boundingRect()
        if self.hasFocus() or self.isSelected():
            painter.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.black, 1,Qt.Qt.SolidLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin)))  painter.drawRect(self.boundingRect())        
        
    def itemChange(self,change,value):
        if change == QtGui.QGraphicsItem.ItemSelectedChange and value == True:
            self.emit(QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),self.mobj)
  return QtGui.QGraphicsItem.itemChange(self,change,value)

class InnerItem(QGObj):
    name = "ITEM"
    def __init__(self,mobj,parent,w,h):
        QGObj.__init__(self, mobj,parent)
        self.gobj = QtGui.QGraphicsRectItem(2, 2, w,h, self)
        self.gobj.mobj = mobj
    
    def setDisplayProperties(self,x,y,textcolor,bgcolor):
        """Set the display properties of this item."""
        self.setGeometry(x-5,y-5, 
                          self.gobj.boundingRect().width(), 
                          self.gobj.boundingRect().height())
        
        #self.gobj.setBrush(QtGui.QBrush(Qt.QColor("white")))

    def paint(self, painter=None, option=None, widget = None):
        # painter.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.red, 5,Qt.Qt.DashLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin)))  # painter.drawRect(self.boundingRect()) 
        if self.hasFocus() or self.isSelected():
            painter.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.black, 1,Qt.Qt.DashLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin)))  painter.drawRect(self.boundingRect())        

    def boundingRect(self):
        ''' reimplimenting boundingRect for redrawning '''
        
        return QtCore.QRectF(self.gobj.boundingRect())
        #return QtCore.QRectF(0,0,self.gobj.boundingRect().width(),self.gobj.boundingRect().height())


class OuterItem(QtGui.QGraphicsRectItem):
    name = "COMPARTMENT"
    def __init__(self,parent,x,y,w,h,item):
        self.cmptEmitter = QtCore.QObject()
        iParent = item
    
        if hasattr(iParent, "__iter__"):
            self.mobj = iParent[0]
        else:
            self.mobj = iParent
        self.layoutWidgetPt = parent
        QtGui.QGraphicsRectItem.__init__(self,x,y,w,h)

        self.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True);
        self.setFlag(QtGui.QGraphicsItem.ItemIsSelectable)
        #self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1)
        self.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, 1) 
    
    def pointerLayoutpt(self):
        return (self.layoutWidgetPt)

    def itemChange(self,change,value):
        if change == QtGui.QGraphicsItem.ItemPositionChange:
            self.cmptEmitter.emit(QtCore.SIGNAL("qgtextPositionChange(PyQt_PyObject)"),self.mobj)
                
        if change == QtGui.QGraphicsItem.ItemSelectedChange and value == True:
           self.cmptEmitter.emit(QtCore.SIGNAL("qgtextItemSelectedChange(PyQt_PyObject)"),self.mobj)
  return QtGui.QGraphicsItem.itemChange(self,change,value)

class childItem(QGObj):
    
    name = "ITEM"
    font = QtGui.QFont(QGObj.defaultFontName)
    font.setPointSize(QGObj.defaultFontSize)
    fontMetrics = QtGui.QFontMetrics(font)
    def __init__(self, mobj, parent):
        QGObj.__init__(self, mobj, parent)
        self.bg = QtGui.QGraphicsRectItem(self)
        self.bg.setAcceptHoverEvents(True)
        self.gobj = QtGui.QGraphicsSimpleTextItem(self.mobj, self.bg)
        self.gobj.mobj = self.mobj
    
        self.gobj.setFont(childItem.font)
        if not childItem.fontMetrics:
            childItem.fontMetrics = QtGui.QFontMetrics(self.gobj.font())
        self.bg.setRect(0, 
                        0, 
                        self.gobj.boundingRect().width()
                        +childItem.fontMetrics.width('  '), 
                        self.gobj.boundingRect().height())
        self.bg.setPen(Qt.QColor(0,0,0,0))
        self.gobj.setPos(childItem.fontMetrics.width(' '), 0)
    
    def setDisplayProperties(self,x,y,textcolor,bgcolor):
        """Set the display properties of this item."""
        self.setGeometry(x, y,self.gobj.boundingRect().width()
                        +childItem.fontMetrics.width(''), 
                        self.gobj.boundingRect().height())
        self.bg.setBrush(QtGui.QBrush(bgcolor))
    
    def boundingRect(self):
        ''' reimplimenting boundingRect for redrawning '''
        return QtCore.QRectF(0,0,self.gobj.boundingRect().width()+childItem.fontMetrics.width(' \
'),self.gobj.boundingRect().height())  
class Window(QtGui.QWidget):
    def __init__(self):
        
        super(Window,self).__init__()
        
        #self.scene = QtGui.QGraphicsScene(self)
        self.scene = GraphicalScene(self)
        self.view = GraphicalView(self.scene)
        
        #OuterBorder
        self.Outer = OuterItem(self,0,0,0,0,"COMPARTMENT")
        self.Outer.setRect(0,0,40,40)
        self.scene.addItem(self.Outer)
        
        self.inner = InnerItem("I1",self.Outer,20,20)
        self.inner.gobj.setPen(QtGui.QPen(QtGui.QPen(QtCore.Qt.blue,8,Qt.Qt.SolidLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin)))  
        self.child = childItem("Topchild",self.inner)
        self.child.setDisplayProperties(100,30,QColor("black"),QColor("blue"))
        
        self.child1 = childItem("bottomchild",self.inner)
        self.child1.setDisplayProperties(250,350,QColor("black"),QColor("red"))
        
        print " AT298 ",self.inner.childItems()
        xpos, ypos = [],[]
        for l in self.inner.childItems():
            if  (not isinstance(l,QtGui.QGraphicsRectItem)):
               xpos.append((l.pos().x())+(l.boundingRect().bottomRight().x()))
               xpos.append(l.pos().x())
               ypos.append(l.pos().y()+l.boundingRect().bottomRight().y())
               ypos.append(l.pos().y())

        print " xpos ",xpos, " ypos ",ypos
 
        if xpos and ypos:
            calculateRectGrp = \
                QtCore.QRectF(min(xpos),min(ypos),(max(xpos)-min(xpos)),(max(ypos)-min(ypos)))
                
        print " calculateRectGrp ",calculateRectGrp, " auto \
",self.inner.childrenBoundingRect()  rectgrp = calculateRectGrp
        rectgrp = self.inner.childrenBoundingRect()
        x = rectgrp.x()
        y = rectgrp.y()
        self.inner.gobj.setRect(x,y,rectgrp.width(),rectgrp.height())
        self.inner.setDisplayProperties(0,0,Qt.QColor("green"),Qt.QColor("yellow"))
        
        print " inner.boundingRect ",self.inner.boundingRect(), " geo \
",self.inner.geometry()  print " inner.gobj rect ",self.inner.gobj.boundingRect()
        #compartment size
        rectcompt = self.Outer.childrenBoundingRect()
        
        self.Outer.setRect(rectcompt.x()-10,rectcompt.y()-10, \
                rectcompt.width()+20,rectcompt.height()+20)
        self.Outer.setPen(QtGui.QPen(Qt.QColor(66,66,66,100), 5, Qt.Qt.SolidLine, \
Qt.Qt.RoundCap, Qt.Qt.RoundJoin))  print " # End #"
        self.view.show()

def run():
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())

run()


["b64ndary.png" (image/png)]
[Attachment #8 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic