Probleme bei Verständnis von paint() (bei QGraphics)

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
lightning2911
User
Beiträge: 4
Registriert: Mittwoch 5. Mai 2010, 12:43

Ich arbeite an einem Projekt wo ich Rechtecke an einem Raster erstellen, selektieren und bewegen kann.

Das selektierte Rechteck soll in einen anderen Farbe dargstellt werden.

In einem MainWindow lausche ich nach einem Tastendruck und wechsle dann eine Modusvariable (newItem). Wenn die True ist, dann wird gezeichnet, sonst selektiert.

Im Scene, lausche ich mousePress, mouseMove, mouseRelease und je nach Modus erstelle ich ein Rechteck oder lasse selektieren und bewegen.

Die Positionen der Maus werden noch über itemChange auf ein Raster geschnappt.

Jetzt mein Problem:

Mit diesem Codeausschnitt, kann ich all das machen was ich möchte, nur wird das selektierte Rechteck mit einer gestrichelten schwarzen Linie und nicht wie im If-Zweig von paint() angegeben mit rotem Rand und gelber Fläche gemalt für isSelected() obwohl ich beim Debugging sehe, dass die Anweisungen ausgeführt werden.

Code: Alles auswählen

class DesignerBlock(QGraphicsRectItem):
    def __init__(self, rect=QRectF(0, 0, 0, 0), parent=None, scene=None):
        super(DesignerBlock, self).__init__(parent, scene)
        self.setFlag(self.ItemIsMovable, True)
        self.setFlag(self.ItemIsSelectable, True)
        self.setFlag(self.ItemSendsGeometryChanges, True)
        self.setPen(QPen(Qt.black, 1, Qt.SolidLine))
        self.setBrush(QBrush(Qt.white, Qt.SolidPattern))
        self.setRect(rect) # <-----
        self.setSelected(True)
        self.setFocus()
    
    def paint(self, painter, option, widget):
        pen = self.pen()
        brush = self.brush()
        if self.isSelected():
            pen = QPen(Qt.red, 1, Qt.SolidLine)
            brush = QBrush(Qt.yellow, Qt.SolidPattern)
        painter.setPen(pen)
        painter.setBrush(brush)
        painter.drawRect(self.rect()) # <-----
        super(DesignerBlock, self).paint(painter, option, widget)
        
    def deferPosition(self, value):
        big = abs(value) / SCREEN_GRID
        little = abs(value) % SCREEN_GRID
        
        if little > (SCREEN_GRID / 2):
            little = 1
        else:
            little = 0
            
        if value > 0:
            direction = 1
        else:
            direction = -1
            
        return (big + little) * SCREEN_GRID * direction
        
    
    def itemChange(self, change, value):
        if change == QGraphicsItem.ItemPositionChange:
            x = value.toPoint().x()
            y = value.toPoint().y()
            newPosition = value.toPoint()

            newPosition.setX(self.deferPosition(x))

            newPosition.setY(self.deferPosition(y))

            return newPosition
        else:
            return value
Wenn ich wie in folgendem Ausschnitt die angemerkten 2 Zeilen verändere (wobei ich dachte, dass es im Endeffekt das selbe macht), wird beim Erstellen eines Rechtecks nur der Ausschnitt der Maus (ohne Anpassung an den Raster) gepainted ABER in rot und gelb!. Wenn ich dann aber Fenster minimieren/maximieren mache und damit ein repaint forciere, sehe ich, dass die Rechtecke "richtig" vollständig gepainted werden.

Aber im Select-Modus kann ich nix selektieren und das Rubberband löscht alles unter sich. Und bewegen tut sich damit auch nix.

Hat jemand eine Idee wo ich für die Lösung ansetzen muss?

Code: Alles auswählen

class DesignerBlock(QGraphicsRectItem):
    def __init__(self, rect=QRectF(0, 0, 0, 0), parent=None, scene=None):
        super(DesignerBlock, self).__init__(parent, scene)
        ...
        self.rect = rect # <----------
        #self.setRect(rect)
        ...
    
    def paint(self, painter, option, widget):
        ...
        painter.drawRect(self.rect) # <-----------
        #painter.drawRect(self.rect())
        super(DesignerBlock, self).paint(painter, option, widget)
Hier noch der Abschnitt in scene, der die Maus überwacht:

Code: Alles auswählen

def mousePressEvent(self, mouseEvent):
        self.startPos = mouseEvent.scenePos()
        self.emit(SIGNAL("startSet"), self.gridPos(self.startPos))
        if self.newItem == False:
            super(DesignerScene, self).mousePressEvent(mouseEvent) 
        
    def mouseMoveEvent(self, mouseEvent):
        self.emit(SIGNAL("updateCoords"), self.gridPos(mouseEvent.scenePos()))
        super(DesignerScene, self).mouseMoveEvent(mouseEvent) 

    def mouseReleaseEvent(self, mouseEvent):
        self.endPos = mouseEvent.scenePos()
        self.emit(SIGNAL("endSet"), self.gridPos(self.endPos))
        if self.newItem:
            self.emit(SIGNAL("createBox"), self.gridPos(self.startPos), self.gridPos(self.endPos))
        else:
            super(DesignerScene, self).mousePressEvent(mouseEvent) 
        
    def createBox(self, start, end):
        xs = start.x()
        ys =  start.y()
        xe =  end.x()
        ye =  end.y()
        if ys <> ye and xs <> xe:
            # insert only if not a line
            self.addItem(DesignerBlock(QRectF(xs, ys, xe-xs, ye-ys).normalized()))
lightning2911
User
Beiträge: 4
Registriert: Mittwoch 5. Mai 2010, 12:43

Lösung: super() in paint() war falsch. Darf nur in einem else von if isSelected() ausgeführt werden.
Antworten