This tip is about how to make pyqt4 rectangle selectable by its edge (or you call it stroke), by default it's selectable by inner area. To achieve this, basically you need to subclass QGraphicsRectItem
and overwrite its shape()
function so that its shape is not an area but a stroke around its bounding path.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | from PyQt4 import QtGui, QtCore
import sys
class QStrokeRect(QtGui.QGraphicsRectItem):
def __init__(self, parent=None):
super(QStrokeRect, self).__init__(parent)
self.strokeWidth = 4
self.setPen(QtGui.QPen(QtGui.QColor(255, 0, 0), 4, QtCore.Qt.SolidLine))
self.setFlags(QtGui.QGraphicsItem.ItemIsSelectable)
def setStrokeWidth(self, strokeWidth):
self.strokeWidth = strokeWidth
def shape(self):
path = QtGui.QPainterPath()
path.addRect(self.boundingRect())
pStroker = QtGui.QPainterPathStroker()
pStroker.setWidth(self.strokeWidth)
return pStroker.createStroke(path)
class QTestView(QtGui.QGraphicsView):
def __init__(self, parent=None):
super(QTestView, self).__init__(parent)
self.scene = QtGui.QGraphicsScene(self)
self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.darkGray, QtCore.Qt.SolidPattern))
self.setScene(self.scene)
class Example(QtGui.QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 500, 500)
self.setWindowTitle('Select by stroke')
self.gv = QTestView(self)
self.gv.setMouseTracking(True)
self.pen = QtGui.QPen(QtGui.QColor(255, 0, 0), 4, QtCore.Qt.SolidLine)
self.gv.scene.addRect(QtCore.QRectF(0,0,400,400), self.pen)
self.gv.scene.addItem(QStrokeRect(QtCore.QRectF(100,100,100,100)))
self.gv.scene.addItem(QStrokeRect(QtCore.QRectF(150,150,100,100)))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
|
Example: the big outer rectangle QGraphicsRectItem
can not select by edge, but the inner two small rectangles QStrokeRect
can be slect by edge.