Highlight hovered cells in QGraphicsScene
-
I am trying to highlight hovered cells on a Grid drawn in a QGraphicsScene.
Previously I had tried to add another transparent QWidget to the Scene, so that this new QWidget is shown above the Scenes drawing.
I tried it like this without any success. The Overlay Widget is never visible as it is covered by the Scenes drawingself.__scene = QtWidgets.QGraphicsScene(self) self.__view = QtWidgets.QGraphicsView(self.__scene, self) self.__overlay = QWidget() # must be toplevel it seems self.__scene.addWidget(self.__overlay)
As a workaround I thought that I can just draw both the Grid AND the Highlight effect (blue rect around the cell) on the Scene. My code now looks as follows. But the problem is, that I will always have to redraw the Highlight when the Grid was redrawn. Apparently the newly drawn Grid will draw over my Highlight. This just feels super hacky
def __drawGrid(self): if self.__grid_cells: # remove prev. grid from scene self.__scene.removeItem(self.__grid_cells) # remove last reference for gc self.__grid_cells = None # create new grid self.__grid_cells = QGraphicsItemGroup() for row_idx, row in enumerate(self.__pattern_model.get_cells()): for stitch_idx, stitch in enumerate(row): x1 = stitch_idx * self.__cell_width y1 = row_idx * self.__cell_height if stitch: pen = QPen(Qt.white, 1, Qt.SolidLine) brush = QBrush(Qt.black) else: pen = QPen(Qt.black, 1, Qt.SolidLine) brush = QBrush(Qt.white) self.__grid_cells.addToGroup( self.__scene.addRect( x1, y1, self.__cell_width, self.__cell_height, pen, brush ) ) self.__scene.addItem(self.__grid_cells) # redraw highlight to put it on top again self.__redraw_highlight() def __redraw_highlight(self): if self.highlighted_cell: self.__scene.removeItem(self.highlighted_cell) self.__scene.addItem(self.highlighted_cell) def __drawHighlight(self, stitch_idx, row_idx): if self.highlighted_cell: self.__scene.removeItem(self.highlighted_cell) x1 = stitch_idx * self.__cell_width y1 = row_idx * self.__cell_height pen = QPen(Qt.blue, 5, Qt.SolidLine) self.highlighted_cell = self.__scene.addRect( x1, y1, self.__cell_width, self.__cell_height, pen )
Is the way I am doing it right now completely wrong? Are there any best or even just better practices for this?
-
Hi,
Why not use a QRubberBand and move it where you want without adding it to the scene ?
-
@occohd21
I see you adding widgets. rectangles and groups. I don't know what your grid is for, but did you at least consider doing it all viadrawBackground()
? That's how I do things like this, and for temporary highlighting I usedrawForeground()
, with a semi-transparent color. There is no adding & removing graphics items. It's a very different approach, depends on your usage.