[PyQt] problems with painting in QGraphics

Christopher M. Nahler christopher.nahler at papermodels.at
Mon May 3 09:28:55 BST 2010


I want to add rectangles to a scene (see the code below) by dragging the 
mouse. To distinguish from selection mode I change a variable 
(self.newItem) due to key pressing and handle this in the mouse_events.

In the class DesignerBlock(QGraphicsRectItem) I am passing a (QRectF) 
type rect which I want the paint method to draw on the scene. Right now 
I am going via intermediate variables to paint as when I try to use the 
rect variable in the paint method I get an error due to incorrect 
overload matching.

When I do use self.rect = rect (and comment self.setRect(rect)) in the 
DesignerBlock init class then I can draw in paint with self.rect but 
then the "selection" mode does not draw a rubberband anymore and erases 
already drawn items under it.

I hope I was succesful at describing what the problem is ...
Any ideas where the problem lies?

from PyQt4.QtCore import *
from PyQt4.QtGui import *

SCREEN_BORDER = 100

class GraphicsView(QGraphicsView):
     def __init__(self, parent=None):
         super(GraphicsView, self).__init__(parent)
         self.setMouseTracking(True)
         self.setDragMode(QGraphicsView.RubberBandDrag)
         self.scale(1,1)

     def wheelEvent(self, event):
         factor = 1.41 ** (-event.delta() / 240.0)
         self.scale(factor, factor)

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.ItemIsFocusable, True)
         self.setFlag(self.ItemIsMovable, True)
         self.setPen(QPen(Qt.black, 1, Qt.SolidLine))
         self.setBrush(QBrush(Qt.white, Qt.SolidPattern))
         self.setRect(rect)
         self.myX = rect.x()
         self.myY = rect.y()
         self.myWidth = rect.width()
         self.myHeight = rect.height()
         print "blk", rect
         print "blk", self.rect
         #self.rect = rect
         # if i use the above then painting works with self.rect
         # but in select mode the mousedragged rectangle deletes drawing 
items
         self.setSelected(True)
         self.setFocus()

     def paint(self, painter, option, widget):
         painter.setPen(self.pen())
         painter.setBrush(self.brush())
         if self.isSelected():
             painter.setPen(Qt.red, 3, Qt.SolidLine)
             painter.setBrush(Qt.yellow, Qt.SolidPattern)
         #painter.drawRect(self.rect)
         painter.drawRect(self.myX, self.myY, self.myWidth, self.myHeight)
         super(DesignerBlock, self).paint(painter, option, widget)

class DesignerScene(QGraphicsScene):

     itemInserted = pyqtSignal(DesignerBlock)
     #itemSelected = pyqtSignal(QGraphicsItem)

     def __init__(self, parent=None):
         super(DesignerScene, self).__init__(parent)
         self.pen = QPen(Qt.black, 1, Qt.SolidLine)
         self.brush = QBrush(Qt.white, Qt.SolidPattern)
         self.newItem = None
         self.startPos = None
         self.endPos = None
         self.setSceneRect(0, 0, 800, 600)

     def drawBackground(self, painter, rect):
         # rect is visible rect
         # draw frame
         painter.setPen(QPen(Qt.red, 0, Qt.NoPen))
         painter.setBrush(QBrush(Qt.lightGray, Qt.SolidPattern))
         painter.drawRect(0, 0, 800, 600)
         # draw grid
         painter.setBrush(QBrush(Qt.darkGray, Qt.SolidPattern))
         for y in range(-1, 601, 50):
             for x in range(-1, 801, 50):
                 if x == -1:
                     x = 0
                 if y == -1:
                     y = 0
                 painter.drawRect(x-1, y-1, 3, 3)

     def keyPressEvent(self, event):
         if event.key() == Qt.Key_A:
             self.newItem = True
         elif event.key() == Qt.Key_Escape:
             self.newItem = False
         super(DesignerScene, self).keyPressEvent(event)

     def mousePressEvent(self, mouseEvent):
         if self.newItem:
             self.startPos = mouseEvent.scenePos()
         else:
             super(DesignerScene, self).mousePressEvent(mouseEvent)

     def mouseReleaseEvent(self, mouseEvent):
         #print "rect: (%d/%d)-(%d/%d)" % (xs, ys, xe, ye)
         if self.newItem:
             self.endPos = mouseEvent.scenePos()
             xs = self.startPos.x()
             ys = self.startPos.y()
             xe = self.endPos.x()
             ye = self.endPos.y()
             # in add item mode
             print "scn", QRectF(xs, ys, xe-xs, ye-ys)
             item = DesignerBlock(QRectF(xs, ys, xe-xs, ye-ys))
             self.addItem(item)
             #self.itemInserted.emit(item)
         else:
             super(DesignerScene, self).mouseReleaseEvent(mouseEvent)

class MainWindow(QMainWindow):

     def __init__(self, parent=None):
         super(MainWindow, self).__init__(parent)
         self.setMouseTracking(True)

         self.scene = DesignerScene()
         self.scene.setSceneRect(QRectF(0, 0, 800, 600))

         #self.scene.itemInserted.connect(self.itemInserted)
         #self.scene.itemSelected.connect(self.itemSelected)

         # add view
         self.view = GraphicsView()
         self.view.setScene(self.scene)
         self.setCentralWidget(self.view)

         status = self.statusBar()
         self.startLabel = QLabel()
         self.startLabel.setText(" Start: 0 ")
         self.endLabel = QLabel()
         self.endLabel.setText(" End: 0 ")
         self.modeLabel = QLabel()
         self.modeLabel.setText(" Mode: Select ")
         status.addPermanentWidget(self.startLabel)
         status.addPermanentWidget(self.endLabel)
         status.addPermanentWidget(self.modeLabel)

         status.setSizeGripEnabled(False)
         status.showMessage("Ready", 5000)

     def keyPressEvent(self, event):
         if event.key() == Qt.Key_A:
                 self.modeLabel.setText(" Mode: Draw ")
         elif event.key() == Qt.Key_Escape:
                 self.modeLabel.setText(" Mode: Select ")
         super(MainWindow, self).keyPressEvent(event)

if __name__ == "__main__":

     import sys

     # setup application object
     app = QApplication(sys.argv)

     # create (parent) main window
     mainWindow = MainWindow()
     rect = QApplication.desktop().availableGeometry()
     #mainWindow.setGeometry(rect.x() + SCREEN_BORDER,
                            #rect.y() + SCREEN_BORDER,
                            #rect.width() - 2 * SCREEN_BORDER,
                            #rect.height() - 2 * SCREEN_BORDER)
     mainWindow.setGeometry(900,
                            100,
                            900,
                            700)
     mainWindow.setMinimumSize(900, 700)
     
mainWindow.setWindowIcon(QIcon("D:\UDaten\pyqt\chap12\DesignerTest.bmp"))
     mainWindow.setWindowTitle("DesignerTest")
     mainWindow.show()

     # run application object
     sys.exit(app.exec_())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20100503/acfa0fa6/attachment.html>


More information about the PyQt mailing list