Größe eines QGraphicsRectItem in QGraphicsItemGroup ändern

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
bdeutung
User
Beiträge: 6
Registriert: Montag 12. August 2013, 16:13

Hallo,
ich habe ein QGraphicsRectItem in eine GraphicsItemGroup eingefügt. in eine Scene habe ich 2 GraphicsItemGroups plaziert, die durch einen Mausklick selektiert werden können (blau umrandet)
Die beiden Gruppen sollen später als Bereiche dienen, in denen weitere Items abgelegt werden.
Wenn eine der Gruppen selektiert ist, soll die Größe des beinhalteten QGraphicsRectItem durch drücken der Taste + vergrößert werden.
Bei der linken Group funktioniert es wunderbar, aber wenn ich die rechte Group vergrößern möchte, stimmt die Umrandung nicht und die
ganze Grafik hat ein aus meiner Sicht undefiniertes Verhalten.
Einen Teil des Codes habe ich angehängt.
Kann jemand nachvollziehen, warum die Selektion der rechten Group "springt"?

Danke schon mal im voraus

Code: Alles auswählen

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

from PyQt4 import QtGui, QtCore
import sys
import math

class CardLayoutArea(QtGui.QGraphicsItemGroup):
    def __init__(self,  position, cardtext, observerName, category):
        super(CardLayoutArea, self).__init__()
        self.setFlags(QtGui.QGraphicsItem.ItemIsSelectable |
                      QtGui.QGraphicsItem.ItemAcceptsInputMethod)
        self.position=position
        self.cardtext=cardtext
        self.layoutTextBox=None
        self.line=None
        self.initCategoryArea()
        self.name = observerName
        self.boxColor= QtGui.QColor(QtCore.Qt.white)

    
    def increaseAreaWidth(self):
        """
        Der Kategoriebereich wird um 10 px verbreitert
        """
        self.setPos(self.position)
        rectBox=self.boardarea.boundingRect()
        self.boardarea.setRect(0, 0, rectBox.width()+10, rectBox.height())
  
        self.addToGroup(self.boardarea)
        self.update(rectBox)


        
    def arangeBox(self, atype):
        if atype=='+':
            self.increaseAreaWidth()
        elif atype=='-':
            self.decreaseAreaWidth()


    def initCategoryArea(self):

        self.boardarea= QtGui.QGraphicsRectItem()
        rectBox=QtCore.QRectF(self.position.x(),self.position.y(), 300, 1200)
        self.boardarea.setRect(rectBox)
        self.addToGroup(self.boardarea)
    
    def paint(self, painter, option, widget=None):
 
        if self.isSelected():    
            painter.setPen(QtGui.QPen(QtCore.Qt.blue, 2, QtCore.Qt.SolidLine))
            SelRec=self.boundingRect()
            mRec=QtCore.QRectF(SelRec)
            painter.drawRect(mRec)
            
        QtGui.QGraphicsItemGroup.paint(self, painter, option, widget) 


class SceneoMode:
    insertitem=0
    selectitem=2
    line=3
    layoutnode=4

class ReviewScene(QtGui.QGraphicsScene):
    InsertItem, InsertCircle, InsertLine, MoveItem  = range(4)
       
    
    
    def __init__(self,  parent=None):
        super(ReviewScene, self).__init__(parent)

        self.myMode=None
        #self.listOfItemsInBoard={}
        self.myItemColor = QtCore.Qt.white
        self.myTextColor = QtCore.Qt.black
        self.myLineColor = QtCore.Qt.black
        self.myFont = QtGui.QFont()
        self.selectedCategoryArea=None

        self.area= CardLayoutArea(QtCore.QPointF( 10,70),'Tatsachen',"1","1")
        self.areaFact= CardLayoutArea(QtCore.QPointF( 420,70),'Ereignisse',"2","2")

        self.addItem(self.areaFact)
        self.addItem(self.area)
        self.setMode(SceneoMode.selectitem)
    
    def setMode(self, mode):
        self.myMode = mode
    
    def mousePressEvent(self, mouseEvent):
        if self.myMode==SceneoMode.selectitem:
            for sitem in self.selectedItems():
                if isinstance(sitem, CardLayoutArea):
                    
                    self.selectedCategoryArea=sitem
                    print self.selectedCategoryArea.cardtext
                    
        QtGui.QGraphicsScene.mousePressEvent(self, mouseEvent)
    
    def keyPressEvent(self, event ):
        key = event.key()
       
        if self.selectedCategoryArea!=None:
            if key == QtCore.Qt.Key_Minus:
                self.selectedCategoryArea.arangeBox('-')
            if key == QtCore.Qt.Key_Plus:
                self.selectedCategoryArea.arangeBox('+')
                
    
class MainWindow(QtGui.QMainWindow):
    """
    Hauptfenster der Anwendung Logframe
    """

   
    def __init__(self):
        """
        Initialisierung des Hauptfensters für die Anwendung.
        """
        QtGui.QMainWindow.__init__(self)
        self.prevPoint = QtCore.QPoint()
        self.resize(800, 600)
        self.setWindowTitle("Titel")
        
        self.createActions()
        self.createMenuBar()
   
        #Zeichenbereich aufbauen
        self.scene = ReviewScene()
        self.scene.setSceneRect(QtCore.QRectF(0, 0, 5000, 5000))

        self.view = QtGui.QGraphicsView(self.scene)
        
        layout = QtGui.QHBoxLayout()

        self.view = QtGui.QGraphicsView(self.scene)
        self.view.scrollContentsBy(30,30)
        layout.addWidget(self.view)

        
        self.widgetGraphicsview = QtGui.QWidget()
        self.widgetGraphicsview.setLayout(layout)
        self.widgetGraphicsview.setEnabled(True)

        self.setCentralWidget(self.widgetGraphicsview)
        
    
    def createMenuBar(self):
        """
        Programmenü wird aufgebaut
        """
        #Action Anwendung beenden 
        exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&beenden', self)  
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application') 
        exitAction.triggered.connect(QtGui.qApp.quit)

    def createActions(self):
        
        self.exitAction = QtGui.QAction("E&xit", self, shortcut="Ctrl+X",
                statusTip="Quit Scenediagram example", triggered=self.close)



app = QtGui.QApplication(sys.argv)
dialog = MainWindow()
dialog.show()
sys.exit(app.exec_())
Hase
User
Beiträge: 101
Registriert: Donnerstag 1. Oktober 2009, 15:17
Wohnort: Bremer Speckgürtel

Hallo,
eine schnelle Lösung hab ich nicht, aber ein paar Anmerkungen:

1. Deine Fehlerbeschreibung kann ich nicht nachvollziehen. Bei mir ist es so: wenn das linke Rechteck ausgewählt ist und dann + gedrückt wird, so wird das rechte Rect vergrößert, beim rechtes ist es umgekehrt.
2. Die Rects kann man erst beim zweiten Klick selektieren, da stimmt was mit der Initialisierung nicht. Wenn es erst mal selektiert war, geht es danach immer beim ersten Click.
3. Da geht irgend was durcheinander mit QGraphicsItemGroup und QGraphicsRectItem. Mit was arbeitest du da? Wenn du ein Rechteck darstellen willst, arbeite mit QGraphicsRectItem. Wenn du die Breite verändern willst, dann ändere die Breite des RectItems. Wenn dieses RectItem einer Group zugehörig ist, dann ändert die Group ihr BoundingRect von ganz allein. An der Group-geometrie brauchst du selbst gar nichts ändern (es sei denn, du weißt genau was du tust). Die ItemGroup ist eine abstrakte Klasse die du nur benutzt, um a) graphicItems zusammenzufassen und b) ein gemeinsames BoundingRect der Gruppenmitglieder abzufragen. Ansonsten würde ich die Finger von den geometrischen Eigenschaften der ItemGroup lassen.
Ich hab das Gefühl, du möchtest die ItemGroup als graphischen Container benutzen. Dein graphischer Container ist aber das RectItem.

Grüße

I.H.
bdeutung
User
Beiträge: 6
Registriert: Montag 12. August 2013, 16:13

Hallo,
vielen Dank für Deine Anmerkungen.
Deine Beschreibung im Punkt eins ist das von mir beschriebene undefinierte Verhalten.
Das RectItem ist nur ein Element das später in die ItemGroup plaziert werden soll. Später sollen noch
Linien außerhalb der RectItems in die ItemGroup plaziert werden.
Meine Idee ist, das ich die Größe der ItemGroup ändere und die enhaltenen Items dann anpasse. Wie Du schon
geschrieben hast ist die ItemGroup mein Container. An diesen sollen sich dann alle enthaltenen Items ausrichten.
So der Plan :?
Danke
bdeutung
Hase
User
Beiträge: 101
Registriert: Donnerstag 1. Oktober 2009, 15:17
Wohnort: Bremer Speckgürtel

Hallo,

meiner Meinung nach ist das der falsche Ansatz. Bei dir wackelt der Schwanz mit dem Hund.

ItemGroups sind Elemente, die mal schnell so "on the fly" dynamisch erzeugt und beim nächsten Klick vielleicht wieder aufgelöst und neu zusammengestellt werden. Eine ItemGroup ist in nur eine Py-Zeile erzeugt und in einer Zeile wieder zerstört.

Bei dir ist die ItemGroup das Basiselement. Was willst du denn machen, wenn du z.B. ein weiteres Item in das Rechteck platzierst und es unabhängig vom Rechteck mit der Maus bewegen willst. Das geht ja gar nicht, dafür müsstest du dein Hauptelement zerstören.

Dein Hauptobjekt CardLayoutArea muss m.E. ein RectItem zurückgeben, und keine ItemGroup. Du willst ein Rechteck darstellen, also lass es doch ein Rechteck sein, warum soll es unbedingt eine Gruppe sein, die nur durch Tricks wie ein Rechteck aussieht?

Eine Gruppe lohnt ja ohnehin nur ab mindestens 2 Items. Und auch nur dann, wenn diese 2 Items gemeinsam selectable oder movable sein sollen, was ja temporär durchaus der Fall sein kann.

Und dann kannst du sie ja immernoch kurzfristig zur Gruppe machen durch sowas wie

Code: Alles auswählen

myItemList=[myMainRect, myOtherItem]
self.mygroup=self.graphicsView.scene().createItemGroup(myItemList)


oder so. Da sparst du dir dieses ganze komplizierte Zusammenspiel zwischen den Gruppen und Rechtecken, so wie es jetzt ist.

Ich hoffe, das war halbwegs verständlich, ansonsten bitte nachfragen.
Hase
User
Beiträge: 101
Registriert: Donnerstag 1. Oktober 2009, 15:17
Wohnort: Bremer Speckgürtel

Noch ein Nachtrag:

Meine Idee ist, das ich die Größe der ItemGroup ändere und die enhaltenen Items dann anpasse.
Genau das meine ich wenn ich sage, bei dir wackelt der Schwanz mit dem Hund.
Eine Gruppe ist immer so groß wie die Items, aus der sie besteht. Nicht die Items passen sich der Gruppe an, nein, die Gruppe passt sich den Items an.


Wenn du einen Bereich haben willst außerhalb des Rechtecks, der irgendwie reagieren soll, dann mach das mit einem zweiten Rechteck, meinetwegen mit unsichtbaren Rändern.
bdeutung
User
Beiträge: 6
Registriert: Montag 12. August 2013, 16:13

Hallo,
hab Deinen Ansatz verfolgt und war erfolgreich.
Vielen Dank !
Antworten