<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#ffffff" text="#000000">
<font face="Courier New, Courier, monospace">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.<br>
<br>
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.<br>
<br>
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.<br>
<br>
I hope I was succesful at describing what the problem is ...<br>
Any ideas where the problem lies?<br>
<br>
from PyQt4.QtCore import *<br>
from PyQt4.QtGui import *<br>
<br>
SCREEN_BORDER = 100<br>
<br>
class GraphicsView(QGraphicsView):<br>
def __init__(self, parent=None):<br>
super(GraphicsView, self).__init__(parent)<br>
self.setMouseTracking(True)<br>
self.setDragMode(QGraphicsView.RubberBandDrag)<br>
self.scale(1,1)<br>
<br>
def wheelEvent(self, event):<br>
factor = 1.41 ** (-event.delta() / 240.0)<br>
self.scale(factor, factor)<br>
<br>
class DesignerBlock(QGraphicsRectItem):<br>
def __init__(self, rect=QRectF(0, 0, 0, 0), parent=None,
scene=None):<br>
super(DesignerBlock, self).__init__(parent, scene)<br>
self.setFlag(self.ItemIsMovable, True)<br>
self.setFlag(self.ItemIsFocusable, True)<br>
self.setFlag(self.ItemIsMovable, True)<br>
self.setPen(QPen(Qt.black, 1, Qt.SolidLine))<br>
self.setBrush(QBrush(Qt.white, Qt.SolidPattern))<br>
self.setRect(rect)<br>
self.myX = rect.x()<br>
self.myY = rect.y()<br>
self.myWidth = rect.width()<br>
self.myHeight = rect.height()<br>
print "blk", rect<br>
print "blk", self.rect<br>
#self.rect = rect<br>
# if i use the above then painting works with self.rect<br>
# but in select mode the mousedragged rectangle deletes drawing
items<br>
self.setSelected(True)<br>
self.setFocus()<br>
<br>
def paint(self, painter, option, widget):<br>
painter.setPen(self.pen())<br>
painter.setBrush(self.brush())<br>
if self.isSelected():<br>
painter.setPen(Qt.red, 3, Qt.SolidLine)<br>
painter.setBrush(Qt.yellow, Qt.SolidPattern)<br>
#painter.drawRect(self.rect)<br>
painter.drawRect(self.myX, self.myY, self.myWidth,
self.myHeight)<br>
super(DesignerBlock, self).paint(painter, option, widget)<br>
<br>
class DesignerScene(QGraphicsScene):<br>
<br>
itemInserted = pyqtSignal(DesignerBlock)<br>
#itemSelected = pyqtSignal(QGraphicsItem)<br>
<br>
def __init__(self, parent=None):<br>
super(DesignerScene, self).__init__(parent)<br>
self.pen = QPen(Qt.black, 1, Qt.SolidLine)<br>
self.brush = QBrush(Qt.white, Qt.SolidPattern)<br>
self.newItem = None<br>
self.startPos = None<br>
self.endPos = None<br>
self.setSceneRect(0, 0, 800, 600)<br>
<br>
def drawBackground(self, painter, rect):<br>
# rect is visible rect<br>
# draw frame<br>
painter.setPen(QPen(Qt.red, 0, Qt.NoPen))<br>
painter.setBrush(QBrush(Qt.lightGray, Qt.SolidPattern))<br>
painter.drawRect(0, 0, 800, 600)<br>
# draw grid<br>
painter.setBrush(QBrush(Qt.darkGray, Qt.SolidPattern))<br>
for y in range(-1, 601, 50):<br>
for x in range(-1, 801, 50):<br>
if x == -1:<br>
x = 0<br>
if y == -1:<br>
y = 0<br>
painter.drawRect(x-1, y-1, 3, 3)<br>
<br>
def keyPressEvent(self, event):<br>
if event.key() == Qt.Key_A:<br>
self.newItem = True<br>
elif event.key() == Qt.Key_Escape:<br>
self.newItem = False <br>
super(DesignerScene, self).keyPressEvent(event)<br>
<br>
def mousePressEvent(self, mouseEvent):<br>
if self.newItem:<br>
self.startPos = mouseEvent.scenePos()<br>
else:<br>
super(DesignerScene, self).mousePressEvent(mouseEvent)<br>
<br>
def mouseReleaseEvent(self, mouseEvent):<br>
#print "rect: (%d/%d)-(%d/%d)" % (xs, ys, xe, ye)<br>
if self.newItem:<br>
self.endPos = mouseEvent.scenePos()<br>
xs = self.startPos.x()<br>
ys = self.startPos.y()<br>
xe = self.endPos.x()<br>
ye = self.endPos.y()<br>
# in add item mode<br>
print "scn", QRectF(xs, ys, xe-xs, ye-ys)<br>
item = DesignerBlock(QRectF(xs, ys, xe-xs, ye-ys))<br>
self.addItem(item)<br>
#self.itemInserted.emit(item)<br>
else:<br>
super(DesignerScene, self).mouseReleaseEvent(mouseEvent)<br>
<br>
class MainWindow(QMainWindow):<br>
<br>
def __init__(self, parent=None):<br>
super(MainWindow, self).__init__(parent)<br>
self.setMouseTracking(True)<br>
<br>
self.scene = DesignerScene()<br>
self.scene.setSceneRect(QRectF(0, 0, 800, 600))<br>
<br>
#self.scene.itemInserted.connect(self.itemInserted)<br>
#self.scene.itemSelected.connect(self.itemSelected)<br>
<br>
# add view<br>
self.view = GraphicsView()<br>
self.view.setScene(self.scene)<br>
self.setCentralWidget(self.view)<br>
<br>
status = self.statusBar()<br>
self.startLabel = QLabel()<br>
self.startLabel.setText(" Start: 0 ")<br>
self.endLabel = QLabel()<br>
self.endLabel.setText(" End: 0 ")<br>
self.modeLabel = QLabel()<br>
self.modeLabel.setText(" Mode: Select ")<br>
status.addPermanentWidget(self.startLabel)<br>
status.addPermanentWidget(self.endLabel)<br>
status.addPermanentWidget(self.modeLabel)<br>
<br>
status.setSizeGripEnabled(False)<br>
status.showMessage("Ready", 5000)<br>
<br>
def keyPressEvent(self, event):<br>
if event.key() == Qt.Key_A:<br>
self.modeLabel.setText(" Mode: Draw ")<br>
elif event.key() == Qt.Key_Escape:<br>
self.modeLabel.setText(" Mode: Select ")<br>
super(MainWindow, self).keyPressEvent(event)<br>
<br>
if __name__ == "__main__":<br>
<br>
import sys<br>
<br>
# setup application object<br>
app = QApplication(sys.argv)<br>
<br>
# create (parent) main window<br>
mainWindow = MainWindow()<br>
rect = QApplication.desktop().availableGeometry()<br>
#mainWindow.setGeometry(rect.x() + SCREEN_BORDER, <br>
#rect.y() + SCREEN_BORDER, <br>
#rect.width() - 2 * SCREEN_BORDER, <br>
#rect.height() - 2 * SCREEN_BORDER)<br>
mainWindow.setGeometry(900, <br>
100, <br>
900, <br>
700)<br>
mainWindow.setMinimumSize(900, 700)<br>
mainWindow.setWindowIcon(QIcon("D:\UDaten\pyqt\chap12\DesignerTest.bmp"))<br>
mainWindow.setWindowTitle("DesignerTest")<br>
mainWindow.show()<br>
<br>
# run application object<br>
sys.exit(app.exec_())</font>
</body>
</html>