Home > Mobile >  How to aviod rubberband become a a line and How to set rubberband only show border line?
How to aviod rubberband become a a line and How to set rubberband only show border line?

Time:05-31

I write a simple app, While drag or scale the MainView, The PartView rubberband will show scene area in PartView.But sometime the rubber-band become a line, and sometime the rubberband disappear.So How to aviod this phenomenon appear?And sometime I want the rubberband only show it's border-line, not contain it's light-blue rectangle,So how can I write code ?

My Code

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import random
import math

r = lambda : random.randint(0, 255)
r255 = lambda : (r(), r(), r())

class Scene(QGraphicsScene):
    def __init__(self):
        super().__init__()
        for i in range(1000):
            item = QGraphicsEllipseItem()
            item.setRect(0, 0, r(), r())
            item.setBrush(QColor(*r255()))
            item.setPos(r()*100, r()*100)
            self.addItem(item)

class MainView(QGraphicsView):
    sigExposeRect = pyqtSignal(QRectF)
    def drawBackground(self, painter: QPainter, rect: QRectF) -> None:
        super().drawBackground(painter, rect)
        self.sigExposeRect.emit(rect)

    def wheelEvent(self, event: QWheelEvent) -> None:
        factor = math.pow(2.7, event.angleDelta().y()/360)
        self.scale(factor, factor)

class PartView(QGraphicsView):
    def __init__(self):
        super().__init__()
        self.r = QRubberBand(QRubberBand.Rectangle, self)
        self.r.setWindowOpacity(1)
        self.r.show()

class View(QSplitter):
    def __init__(self):
        super().__init__()
        self.m = MainView()
        self.m.setMouseTracking(True)
        self.m.setDragMode(QGraphicsView.ScrollHandDrag)
        self.m.sigExposeRect.connect(self.onExposeRect)

        self.p = PartView()

        self.m.setScene(Scene())
        self.p.setScene(self.m.scene())
        self.p.fitInView(self.m.scene().itemsBoundingRect())

        self.addWidget(self.m)
        self.addWidget(self.p)

    def onExposeRect(self, rect: QRectF):
        prect = self.p.mapFromScene(rect).boundingRect()
        self.p.r.setGeometry(prect)

app = QApplication([])
v = View()
v.show()
app.exec()

My Result enter image description here

CodePudding user response:

I think the problem is that the qrect passed to the drawBackground method is only includes the portion of the background that wasn't previously in the viewport. Not positive about that though.

Either way I was able to achieve your goal of avoiding only a section of the rubber band being drawn, by sending the area for the entire viewport to the onExposeRect slot.


class MainView(QGraphicsView):
    sigExposeRect = pyqtSignal(QRectF)
    def drawBackground(self, painter: QPainter, rect: QRectF) -> None:
        # Adding this next line was the only change I made
        orect = self.mapToScene(self.viewport().geometry()).boundingRect() 
        super().drawBackground(painter, rect)
        self.sigExposeRect.emit(orect)  # and passing it to the slot.

    def wheelEvent(self, event: QWheelEvent) -> None:
        factor = math.pow(2.7, event.angleDelta().y()/360)
        self.scale(factor, factor)


  • Related