Probleme bei Verständnis von paint() (bei QGraphics)
Verfasst: Mittwoch 5. Mai 2010, 13:14
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.
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?
Hier noch der Abschnitt in scene, der die Maus überwacht:
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
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)
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()))