[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