def paintEvent(self, event): painter = QPainter(self) painter.setClipRegion(event.region()) if ( self.testPaintAttribute(self.BackingStore) and self.__data.backingStore is not None ): bs = self.__data.backingStore if QT_MAJOR_VERSION >= 5: pixelRatio = bs.devicePixelRatio() else: pixelRatio = 1.0 if bs.size() != self.size() * pixelRatio: bs = QwtPainter.backingStore(self, self.size()) if self.testAttribute(Qt.WA_StyledBackground): p = QPainter(bs) qwtFillBackground(p, self) self.drawCanvas(p, True) else: p = QPainter() if self.__data.borderRadius <= 0.0: # print('**DEBUG: QwtPlotCanvas.paintEvent') QwtPainter.fillPixmap(self, bs) p.begin(bs) self.drawCanvas(p, False) else: p.begin(bs) qwtFillBackground(p, self) self.drawCanvas(p, True) if self.frameWidth() > 0: self.drawBorder(p) p.end() painter.drawPixmap(0, 0, self.__data.backingStore) else: if self.testAttribute(Qt.WA_StyledBackground): if self.testAttribute(Qt.WA_OpaquePaintEvent): qwtFillBackground(painter, self) self.drawCanvas(painter, True) else: self.drawCanvas(painter, False) else: if self.testAttribute(Qt.WA_OpaquePaintEvent): if self.autoFillBackground(): qwtFillBackground(painter, self) qwtDrawBackground(painter, self) else: if self.borderRadius() > 0.0: clipPath = QPainterPath() clipPath.addRect(self.rect()) clipPath = clipPath.subtracted(self.borderPath(self.rect())) painter.save() painter.setClipPath(clipPath, Qt.IntersectClip) qwtFillBackground(painter, self) qwtDrawBackground(painter, self) painter.restore() self.drawCanvas(painter, False) if self.frameWidth() > 0: self.drawBorder(painter) if self.hasFocus() and self.focusIndicator() == self.CanvasFocusIndicator: self.drawFocusIndicator(painter)
def drawPrimitive(self, pe, opt, p: QtGui.QPainter, widget): # QToolButton elements: # 13: PE_PanelButtonCommand (Fusion) - Fusion button background, called from 15 and 24 calls # 15: PE_PanelButtonTool (Windows, Fusion) - left part background (XP/Vista styles do not draw it with `drawPrimitive`) # 19: PE_IndicatorArrowDown (Windows, Fusion) - right part down arrow (XP/Vista styles draw it in 24 call) # 24: PE_IndicatorButtonDropDown (Windows, XP, Vista, Fusion) - right part background (+arrow for XP/Vista) # # Arrow is drawn along with PE_IndicatorButtonDropDown (XP/Vista) # https://github.com/qt/qtbase/blob/0c51a8756377c40180619046d07b35718fcf1784/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp#L1406 # https://github.com/qt/qtbase/blob/0c51a8756377c40180619046d07b35718fcf1784/src/plugins/styles/windowsvista/qwindowsxpstyle.cpp#L666 # drawBackground paints with DrawThemeBackgroundEx WinApi function # https://docs.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-drawthemebackgroundex if (self.stylename in self.win_modern and pe == self.PE_IndicatorButtonDropDown): pe = self.PE_IndicatorArrowDown # see below if pe == self.PE_IndicatorArrowDown: opt_ = QtWidgets.QStyleOptionToolButton() widget.initStyleOption(opt_) rc = super().subControlRect(self.CC_ToolButton, opt_, self.SC_ToolButtonMenu, widget) if self.stylename in self.win_modern: # By default PE_IndicatorButtonDropDown draws arrow along # with right button art. Draw 2px clipped left part instead path = QtGui.QPainterPath() path.addRect(QtCore.QRectF(rc)) p.setClipPath(path) super().drawPrimitive(self.PE_PanelButtonTool, opt, p, widget) # centered square rc.moveTop(int((rc.height() - rc.width()) / 2)) rc.setHeight(rc.width()) # p.setRenderHint(p.Antialiasing) p.drawPixmap(rc, self.arrow_pix, QtCore.QRect()) else: super().drawPrimitive(pe, opt, p, widget)