def calculateHeight(self): """ Calculate window height adjusting to sequence height with possible ions and set default setting in case of no ions. """ prefix = self._pep.prefix suffix = self._pep.suffix if suffix == {}: max_ion_suff = 1 else: max_ion_suff = len(suffix[max(suffix, key=lambda key: len(suffix[key]))]) if prefix == {}: max_ion_pre = 1 else: max_ion_pre = len(prefix[max(prefix, key=lambda key: len(prefix[key]))]) metrics_pep = QFontMetricsF(self._pep.getFont_Pep()) height_pep = metrics_pep.height() metrics_ion = QFontMetricsF(self._pep.getFont_Ion()) height_ion = metrics_ion.height() # window height calculated with the sum of max prefix and suffix height height_ion_pre = (height_ion * max_ion_pre + 15) SequenceIonsWidget.SUFFIX_HEIGHT = (height_ion * max_ion_suff + 5) SequenceIonsWidget.HEIGHT = height_pep + height_ion_pre + SequenceIonsWidget.SUFFIX_HEIGHT
def _drawLabels(self, painter: QPainter): """отображение подписей на осях""" f_m = QFontMetricsF(self._style['grid']['font']) pen = painter.pen() text = 'Расход, м³/сутки' offset_x = self._margins[0] + self.getDrawArea().width() / 2 offset_x -= f_m.width(text) / 2 offset_y = self.height() - self._margins[3] + f_m.height() offset_y += 20 painter.setPen(self._style['grid']['border']) painter.drawText(QPointF(offset_x, offset_y), text) text = 'Напор, м' offset_x = 0 - f_m.height() - 5 self._drawLabel(painter, f_m, offset_x, text) text = 'Мощность, кВт' offset_x = self._margins[0] + self.getDrawArea().width() + 10 painter.setPen(self._charts['etl_pwr'].pen) self._drawLabel(painter, f_m, offset_x, text) text = 'КПД, %' offset_x = self._margins[0] + self.getDrawArea().width() + \ self._grid_divs['y1'].width + 40 painter.setPen(self._charts['etl_eff'].pen) self._drawLabel(painter, f_m, offset_x, text) painter.setPen(pen)
def sizeHint(self): metrics = QFontMetricsF(self.editor.font()) size_hint = QSize(metrics.height(), metrics.height()) if size_hint.width() > 16: size_hint.setWidth(16) return size_hint
def setupSceneItems(self): if Colors.showFps: self.fpsLabel = DemoTextItem("FPS: --", Colors.buttonFont(), Qt.white, -1, None, DemoTextItem.DYNAMIC_TEXT) self.fpsLabel.setZValue(1000) self.fpsLabel.setPos(Colors.stageStartX, 600 - QFontMetricsF(Colors.buttonFont()).height() - 5) self.mainSceneRoot = QGraphicsWidget() self.scene.addItem(self.mainSceneRoot) self.companyLogo = ImageItem( QImage(self.imagesDir + '/trolltech-logo.png'), 1000, 1000, None, True, 0.5) self.qtLogo = ImageItem(QImage(self.imagesDir + '/qtlogo_small.png'), 1000, 1000, None, True, 0.5) self.companyLogo.setZValue(100) self.qtLogo.setZValue(100) self.pausedLabel = DemoTextItem("PAUSED", Colors.buttonFont(), Qt.white, -1, None) self.pausedLabel.setZValue(100) fm = QFontMetricsF(Colors.buttonFont()) self.pausedLabel.setPos(Colors.stageWidth - fm.width("PAUSED"), 590 - fm.height()) self.pausedLabel.setRecursiveVisible(False)
def setupSceneItems(self): if Colors.showFps: self.fpsLabel = DemoTextItem("FPS: --", Colors.buttonFont(), Qt.white, -1, None, DemoTextItem.DYNAMIC_TEXT) self.fpsLabel.setZValue(1000) self.fpsLabel.setPos( Colors.stageStartX, 600 - QFontMetricsF(Colors.buttonFont()).height() - 5) self.mainSceneRoot = QGraphicsWidget() self.scene.addItem(self.mainSceneRoot) self.companyLogo = ImageItem( QImage(self.imagesDir + '/trolltech-logo.png'), 1000, 1000, None, True, 0.5) self.qtLogo = ImageItem(QImage(self.imagesDir + '/qtlogo_small.png'), 1000, 1000, None, True, 0.5) self.companyLogo.setZValue(100) self.qtLogo.setZValue(100) self.pausedLabel = DemoTextItem("PAUSED", Colors.buttonFont(), Qt.white, -1, None) self.pausedLabel.setZValue(100) fm = QFontMetricsF(Colors.buttonFont()) self.pausedLabel.setPos(Colors.stageWidth - fm.width("PAUSED"), 590 - fm.height()) self.pausedLabel.setRecursiveVisible(False)
def setFontMetrics(): """ Application must be running before you mess too much with Fonts in Qt5 """ global SEQUENCEFONT global SEQUENCEFONTMETRICS global SEQUENCEFONTCHARWIDTH global SEQUENCEFONTCHARHEIGHT global SEQUENCEFONTEXTRAWIDTH global SEQUENCETEXTXCENTERINGOFFSET global SEQUENCETEXTYCENTERINGOFFSET SEQUENCEFONT = QFont("Monaco") if hasattr(QFont, 'Monospace'): SEQUENCEFONT.setStyleHint(QFont.Monospace) SEQUENCEFONT.setFixedPitch(True) SEQUENCEFONTH = int(PATH_BASE_WIDTH / 3.) SEQUENCEFONT.setPixelSize(SEQUENCEFONTH) SEQUENCEFONTMETRICS = QFontMetricsF(SEQUENCEFONT) SEQUENCEFONTCHARWIDTH = SEQUENCEFONTMETRICS.width("A") SEQUENCEFONTCHARHEIGHT = SEQUENCEFONTMETRICS.height() SEQUENCEFONTEXTRAWIDTH = PATH_BASE_WIDTH - SEQUENCEFONTCHARWIDTH SEQUENCEFONT.setLetterSpacing(QFont.AbsoluteSpacing, SEQUENCEFONTEXTRAWIDTH) SEQUENCETEXTXCENTERINGOFFSET = SEQUENCEFONTEXTRAWIDTH / 4. SEQUENCETEXTYCENTERINGOFFSET = PATH_BASE_WIDTH * 0.6
def minimumSizeHint(self): font = QFont(self.font()) font.setPointSize(font.pointSize() - 1) fm = QFontMetricsF(font) return QSize( fm.width(FractionSlider.WSTRING) * self.__denominator, (fm.height() * 4) + FractionSlider.YMARGIN)
def __init__(self, lbl='', onColor='green', offColor='red', initialState=False, maxSize=50, position=1, parent=None, callback=None, alignment=1, valignment=1): QFrame.__init__(self, parent) self.numberControl = ToggleSwitch(onColor, offColor, initialState, maxSize, parent, callback) if position < 3: layout = QVBoxLayout() else: layout = QHBoxLayout() self.lbl = lbl self.lblcontrol = QLabel(lbl, self) if position == 3: # left of switch self.lblcontrol.setAlignment(Qtc.AlignRight) elif position == 4: # right of switch self.lblcontrol.setAlignment(Qtc.AlignLeft) else: # Above or below self.lblcontrol.setAlignment(Qtc.AlignCenter) # add top or left if len(lbl) > 0: if position == 1 or position == 3: layout.addWidget(self.lblcontrol) layout.addWidget(self.numberControl) # Add bottom or right if len(lbl) > 0: if position == 2 or position == 4: layout.addWidget(self.lblcontrol) if alignment == 1: halign = Qtc.AlignCenter elif alignment == 2: halign = Qtc.AlignLeft else: halign = Qtc.AlignRight if valignment == 1: valign = Qtc.AlignVCenter elif valignment == 2: valign = Qtc.AlignTop else: valign = Qtc.AlignBottom layout.setAlignment(halign | valign) # layout.setAlignment(Qtc.AlignCenter | Qtc.AlignVCenter) self.setLayout(layout) textfont = self.lblcontrol.font() metrics = QFontMetricsF(textfont) maxWidth = max( (maxSize+4),(maxSize*2 + metrics.width(lbl)) ) maxHeight = max( (maxSize/2+4),(maxSize/2 + metrics.height()+2) ) #print('Min size: ' + str(maxWidth) + " x " + str(maxHeight)) self.setMinimumSize(int(maxWidth), int(maxHeight)) self.show()
def __init__(self, lbl='', onColor='green', offColor='red', initialState=False, maxSize=80, position=1, alignment=1, valignment=1, parent=None): QFrame.__init__(self, parent) self.numberControl = LEDIndicator(onColor, offColor, initialState, maxSize, parent) if position < 3: layout = QVBoxLayout() else: layout = QHBoxLayout() if len(lbl) == 0: lbl = " " self.lbl = lbl self.lblcontrol = QLabel(lbl, self) self.lblcontrol.setAlignment(Qtc.AlignCenter) # add top or left if len(lbl) > 0: if position == 1 or position == 3: layout.addWidget(self.lblcontrol) else: self.hasLabel = False layout.addWidget(self.numberControl) # Add bottom or right if len(lbl) > 0: if position == 2 or position == 4: layout.addWidget(self.lblcontrol) if alignment == 1: halign = Qtc.AlignCenter elif alignment == 2: halign = Qtc.AlignLeft else: halign = Qtc.AlignRight if valignment == 1: valign = Qtc.AlignVCenter elif valignment == 2: valign = Qtc.AlignTop else: valign = Qtc.AlignBottom layout.setAlignment(halign | valign) self.setLayout(layout) if (len(lbl) > 0): textfont = self.lblcontrol.font() metrics = QFontMetricsF(textfont) maxWidth = max( (maxSize+30),(maxSize + metrics.width(lbl)+4) ) maxHeight = max( (maxSize+35),(maxSize + metrics.height()+2) ) self.setMinimumSize(maxWidth, maxHeight) else: self.setMinimumSize(maxSize+2, maxSize+2) self.show()
def resizeEvent(self, event=None): fm = QFontMetricsF(self.font()) x = (self.width() - self.label.width()) / 2 y = self.height() - (fm.height() * 2) self.label.move(x, y) y = self.height() / 60.0 x = (self.width() / 4.0) - self.leftSpinBox.width() self.leftSpinBox.move(x, y) x = self.width() - (self.width() / 4.0) self.rightSpinBox.move(x, y) # 左上角为(0,0)移动点以左上角为标准
def prepare(self, axis: Axis): """подготовка делений для оси""" # logger.debug(f"{self.prepare.__doc__} {self.name}") f_m = QFontMetricsF(self.font) self.divs.clear() for _, div in axis.generateDivSteps(): div = round(div, 7) self.divs.append(div) self.updateWidth(str(div), f_m) self.height = f_m.height() self.is_ready = True
def minimumSizeHint(self): '''定义字体、字体大小、根据字体Metrics的大小返回一个QSize对象,设置最小的尺寸''' font = QFont(self.font()) # 这声明了和没有声明有什么区别?Constructs a font that is a copy of font. # self.font() This property describes the widget's requested font. # font = QFont() # 只需要一个实例,因为此函数的目的是返回一个QSize font.setPointSize(font.pointSize() - 1) # The point size must be greater than zero. # pointSize() Returns -1 if the font size was specified in pixels. fm = QFontMetricsF(font) # print(fm.height(),fm.width(FractionSlider.WSTRING),fm.width(FractionSlider.WSTRING+'666')) # Return 11.0 18.0 36.0 return QSize(fm.width(FractionSlider.WSTRING) * self.__denominator, (fm.height() * 4) + FractionSlider.YMARGIN)
def _resize(self): """ The integer 8 represents the additional space needed for the in addition drawn lines. The 18 represents the monospace width. """ if self._pep.seqLength != 0: SequenceIonsWidget.WIDTH = \ (self._pep.seqLength * 18.0) + \ (self._pep.seqLength - 1.0) * 8.0 # calculate heights prefix: dict = self._pep.prefix suffix: dict = self._pep.suffix if suffix == {}: max_ion_suff = 1 else: max_ion_suff = len(suffix[max(suffix, key=lambda key: len(suffix[key]))]) if prefix == {}: max_ion_pre = 1 else: max_ion_pre = len(prefix[max(prefix, key=lambda key: len(prefix[key]))]) metrics_pep = QFontMetricsF(self._pep.getFont_Pep()) metrics_ion = QFontMetricsF(self._pep.getFont_Ion()) height_pep = metrics_pep.height() height_ion = metrics_ion.height() # window height calculated with the sum of max prefix and suffix height height_ion_pre = height_ion * max_ion_pre + 15.0 SequenceIonsWidget.SUFFIX_HEIGHT = height_ion * max_ion_suff + 5.0 SequenceIonsWidget.HEIGHT = \ ( height_pep + height_ion_pre + SequenceIonsWidget.SUFFIX_HEIGHT )
def _drawGridDivs_y(self, painter: QPainter, step: float, axis_name='y'): """отрисовка значений делений на оси Y""" if len(self._charts) > 0: logger.debug(f"{self._drawGridDivs_y.__doc__} {axis_name}") axis: Axis = self._charts[self._base_chart].getAxis(axis_name) fm = QFontMetricsF(self._style['grid']['font']) for i, div in axis.generateDivSteps(): text = str(round(div, 8)) offset_x = self._margins[0] - fm.width(text) - 10 offset_y = self.height() - self._margins[3] + fm.height() / 4.0 painter.drawText(QPointF(offset_x, offset_y - i * step), text)
def _drawGridDivs_x(self, painter: QPainter, step: float): """отрисовка значений делений на оси X""" if len(self._charts) > 0: logger.debug(self._drawGridDivs_x.__doc__) axis: Axis = self._charts[self._base_chart].getAxis('x') fm = QFontMetricsF(self._style['grid']['font']) for i, div in axis.generateDivSteps(): text = str(round(div, 8)) offset_x = self._margins[0] - fm.boundingRect(text).width() / 2.0 offset_y = self.height() - self._margins[3] + fm.height() + 5 painter.drawText(QPointF(offset_x + i * step, offset_y), text)
def _drawGridDivs_x(self, painter: QPainter, step: float): """отрисовка значений делений на оси X""" if not self._grid_divs['x0'].is_ready: return # logger.debug(self._drawGridDivs_x.__doc__) f_m = QFontMetricsF(self._style['grid']['font']) divs = self._grid_divs['x0'].divs pen = painter.pen() painter.setPen(self._style['grid']['border']) for i, div in enumerate(divs): text = str(div) offset_x = self._margins[0] - f_m.boundingRect(text).width() / 2.0 offset_y = self.height() - self._margins[3] + f_m.height() + 5 painter.drawText(QPointF(offset_x + i * step, offset_y), text) painter.setPen(pen)
def paintEvent(self, event=None): font = QFont(self.font()) font.setPointSize(font.pointSize() - 1) fm = QFontMetricsF(font) fracWidth = fm.width(FractionSlider.WSTRING) indent = fm.boundingRect("9").width() / 2.0 if not X11: fracWidth *= 1.5 span = self.width() - (FractionSlider.XMARGIN * 2) value = self.__numerator / float(self.__denominator) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) painter.setPen(self.palette().color(QPalette.Mid)) painter.setBrush(self.palette().brush(QPalette.AlternateBase)) painter.drawRect(self.rect()) segColor = QColor(Qt.green).darker(120) segLineColor = segColor.darker() painter.setPen(segLineColor) painter.setBrush(segColor) painter.drawRect(FractionSlider.XMARGIN, FractionSlider.YMARGIN, span, fm.height()) textColor = self.palette().color(QPalette.Text) segWidth = span / self.__denominator segHeight = fm.height() * 2 nRect = fm.boundingRect(FractionSlider.WSTRING) x = FractionSlider.XMARGIN yOffset = segHeight + fm.height() for i in range(self.__denominator + 1): painter.setPen(segLineColor) painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight) painter.setPen(textColor) y = segHeight rect = QRectF(nRect) rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) # painter.drawText(rect, Qt.AlignCenter, # QString.number(i)) painter.drawText(rect, Qt.AlignCenter, str(i)) y = yOffset rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) painter.drawText(rect, Qt.AlignCenter, str(self.__denominator)) painter.drawLine(QPointF(rect.left() + indent, y), QPointF(rect.right() - indent, y)) x += segWidth span = int(span) y = FractionSlider.YMARGIN - 0.5 triangle = [ QPointF(value * span, y), QPointF((value * span) + (2 * FractionSlider.XMARGIN), y), QPointF((value * span) + FractionSlider.XMARGIN, fm.height()) ] painter.setPen(Qt.yellow) painter.setBrush(Qt.darkYellow) painter.drawPolygon(QPolygonF(triangle))
def _drawGridDivs_y(self, painter: QPainter, step: float, axis_name='y0'): """отрисовка значений делений на оси Y""" # logger.debug(f"{self._drawGridDivs_y.__doc__} {axis_name}") f_m = QFontMetricsF(self._style['grid']['font']) divs = self._grid_divs[axis_name].divs pen = painter.pen() painter.setPen(self._style['grid']['border']) for i in range(1, len(divs)): text = str(divs[i]) offset_x = 0.0 if axis_name == 'y0': offset_x = self._margins[0] - f_m.width(text) - 10 elif axis_name == 'y1': offset_x = self._margins[0] + self.getDrawArea().width() + 10 painter.setPen(self._charts['etl_pwr'].pen) elif axis_name == 'y2': offset_x = self._margins[0] + self.getDrawArea().width() + \ self._grid_divs['y1'].width + 40 painter.setPen(self._charts['etl_eff'].pen) offset_y = self.height() - self._margins[3] + f_m.height() / 4.0 painter.drawText(QPointF(offset_x, offset_y - i * step), text) painter.setPen(pen)
def paintEvent(self, e): # ref: https://forums.khronos.org/showthread.php/62124 # self._projection = perspective(30 * self.height() / 512, self.width() / self.height(), 0.01, 100) s = 1 / tan(radians(self._state.projection_fov) / 2) self._projection = perspective2(s * 512 / self.height(), s * 512 / self.width(), 0.01, 100) self._viewport = viewport(0, self.height(), self.width(), -self.height()) self._crop_corners = list(product(*self._state.volume_crop)) pts = [self._project(c) for c in self._crop_corners] top_left = [ min([c[i] - self._screen_bounds_padding for c in pts]) for i in range(2) ] bottom_right = [ max([c[i] + self._screen_bounds_padding for c in pts]) for i in range(2) ] self._screen_bounds_render = [[ quantized_floor(x, self._scale_render) for x in top_left ], [quantized_ceil(x, self._scale_render) for x in bottom_right]] self._screen_bounds_display = [[ quantized_floor(x, self._scale_display) for x in top_left ], [quantized_ceil(x, self._scale_display) for x in bottom_right]] self._resolution_render = ( (numpy.array(self._screen_bounds_render[1]) - self._screen_bounds_render[0]) // self._scale_render).astype( numpy.intp) painter = QPainter(self) # background if self._transparency: painter.fillRect(self.rect(), Qt.magenta) else: painter.fillRect(self.rect(), Qt.black) # volume self._draw_volume(painter) # annotations if self._annotations > 0: painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.TextAntialiasing) self._draw_volume_axes(painter) self._draw_volume_bounding_box(painter) metrics = QFontMetricsF(painter.font()) pen = QPen() pen.setColor(QColor(255, 255, 255)) painter.setPen(pen) dt = numpy.mean(self._render_times or [0]) self._render_times = self._render_times[-10:] lines = [ (2, f'{self._state.display_volume.renderer.type} {1e3*dt:6.1f} ms {1/(dt+1e-6):6.1f} fps'), (2, f'{self._resolution_display[0]} \u00d7 {self._resolution_display[1]} px'.ljust(15) \ + f'{self._state.display_volume.shape[0]} \u00d7 {self._state.display_volume.shape[1]} \u00d7 {self._state.display_volume.shape[2]} vx'), (1, f'{self._state.volume_position+1} of {self._state.volume_count}'), (1, f'{self._resolution_render[0]} \u00d7 {self._resolution_render[1]} px'), (2, f'{self._state.acquired_shape_mm[0]:.2f} \u00d7 {self._state.acquired_shape_mm[1]:.2f} \u00d7 {self._state.acquired_shape_mm[2]:.2f} mm'), (2, f'{self._state.acquired_shape_vx[0]} \u00d7 {self._state.acquired_shape_vx[1]} \u00d7 {self._state.acquired_shape_vx[2]} vx'), (1, self._state.filename), ] i = 0 for (lvl, line) in reversed(lines): if self._annotations >= lvl: painter.drawText( 3, self.height() - i * metrics.height() - metrics.descent() - 2, line) i += 1 scale_factor, _, angles, translation, _ = decompose_matrix( self._view * self._model) lines = [ (1, f'{degrees(angles[0]):+6.1f}\u00b0 {degrees(angles[1]):+6.1f}\u00b0 {degrees(angles[2]):+6.1f}\u00b0' ), ] i = 0 for (lvl, line) in reversed(lines): if self._annotations >= lvl: painter.drawText( self.width() - 3 - metrics.boundingRect(line).width(), self.height() - i * metrics.height() - metrics.descent() - 2, line) i += 1 if self._annotations >= 2: if self._status_text: rect = metrics.boundingRect(self._status_text) painter.drawText(self.width() - rect.width() - 3, rect.height(), self._status_text)
def paintEvent(self, event=None): LogicalSize = 100.0 def logicalFromPhysical(length, side): return (length / side) * LogicalSize fm = QFontMetricsF(self.font()) ymargin = ( (LogicalSize / 30.0) + logicalFromPhysical(self.leftSpinBox.height(), self.height())) ymax = (LogicalSize - logicalFromPhysical(fm.height() * 2, self.height())) width = LogicalSize / 4.0 cx, cy = LogicalSize / 2.0, LogicalSize / 3.0 ax, ay = cx - (2 * width), ymargin bx, by = cx - width, ay dx, dy = cx + width, ay ex, ey = cx + (2 * width), ymargin fx, fy = cx + (width / 2), cx + (LogicalSize / 24.0) gx, gy = fx, ymax hx, hy = cx - (width / 2), ymax ix, iy = hx, fy painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) side = min(self.width(), self.height()) painter.setViewport((self.width() - side) / 2, (self.height() - side) / 2, side, side) painter.setWindow(0, 0, LogicalSize, LogicalSize) painter.setPen(Qt.NoPen) # 因为不需要显示所有线条,因此最后进行绘制,这里写NoPen gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) gradient.setColorAt(0, Qt.white) a = self.leftSpinBox.value() gradient.setColorAt(1, (Qt.red if a != 0 else Qt.white)) painter.setBrush(QBrush(gradient)) # 其可以接受一个QColor对象,也可以接受一个QBrush实例。 # QBrush可以接受QColor、QGlobalColor、QImage、gradient对象 # painter.setBrush(Qt.red) painter.drawPolygon( QPolygonF([ QPointF(ax, ay), QPointF(bx, by), QPointF(cx, cy), QPointF(ix, iy) ])) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) # The QLinearGradient class is used in combination with QBrush to specify a linear gradient brush. # args(QPointF,QPointF): Constructs a linear gradient with interpolation area between the given start point and finalStop. gradient.setColorAt(0, Qt.white) # Creates a stop point at the given position with the given color. The given position must be in the range 0 to 1. b = self.rightSpinBox.value() gradient.setColorAt(1, (Qt.blue if b != 0 else Qt.white)) painter.setBrush(QBrush(gradient)) painter.drawPolygon( QPolygonF([ QPointF(cx, cy), QPointF(dx, dy), QPointF(ex, ey), QPointF(fx, fy) ])) if (a + b) == 0: color = QColor(Qt.white) else: ashare = (a / (a + b)) * 255.0 bshare = 255.0 - ashare color = QColor(ashare, 0, bshare) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) gradient.setColorAt(0, Qt.white) gradient.setColorAt(1, color) painter.setBrush(QBrush(gradient)) painter.drawPolygon( QPolygonF([ QPointF(cx, cy), QPointF(fx, fy), QPointF(gx, gy), QPointF(hx, hy), QPointF(ix, iy) ])) painter.setPen(Qt.black) painter.drawPolyline( QPolygonF([QPointF(ax, ay), QPointF(ix, iy), QPointF(hx, hy)])) painter.drawPolyline( QPolygonF([QPointF(gx, gy), QPointF(fx, fy), QPointF(ex, ey)])) painter.drawPolyline( QPolygonF([QPointF(bx, by), QPointF(cx, cy), QPointF(dx, dy)]))
def paintEvent(self, event=None): LogicalSize = 100.0 def logicalFromPhysical(length, side): return (length / side) * LogicalSize fm = QFontMetricsF(self.font()) ymargin = ( (LogicalSize / 30.0) + logicalFromPhysical(self.leftSpinBox.height(), self.height())) ymax = (LogicalSize - logicalFromPhysical(fm.height() * 2, self.height())) width = LogicalSize / 4.0 cx, cy = LogicalSize / 2.0, LogicalSize / 3.0 ax, ay = cx - (2 * width), ymargin bx, by = cx - width, ay dx, dy = cx + width, ay ex, ey = cx + (2 * width), ymargin fx, fy = cx + (width / 2), cx + (LogicalSize / 24.0) gx, gy = fx, ymax hx, hy = cx - (width / 2), ymax ix, iy = hx, fy painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) side = min(self.width(), self.height()) painter.setViewport((self.width() - side) / 2, (self.height() - side) / 2, side, side) painter.setWindow(0, 0, LogicalSize, LogicalSize) painter.setPen(Qt.NoPen) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) gradient.setColorAt(0, Qt.white) a = self.leftSpinBox.value() gradient.setColorAt(1, (Qt.red if a != 0 else Qt.white)) painter.setBrush(QBrush(gradient)) painter.drawPolygon( QPolygonF([ QPointF(ax, ay), QPointF(bx, by), QPointF(cx, cy), QPointF(ix, iy) ])) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) gradient.setColorAt(0, Qt.white) b = self.rightSpinBox.value() gradient.setColorAt(1, (Qt.blue if b != 0 else Qt.white)) painter.setBrush(QBrush(gradient)) painter.drawPolygon( QPolygonF([ QPointF(cx, cy), QPointF(dx, dy), QPointF(ex, ey), QPointF(fx, fy) ])) if (a + b) == 0: color = QColor(Qt.white) else: ashare = (a / (a + b)) * 255.0 bshare = 255.0 - ashare color = QColor(ashare, 0, bshare) gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100)) gradient.setColorAt(0, Qt.white) gradient.setColorAt(1, color) painter.setBrush(QBrush(gradient)) painter.drawPolygon( QPolygonF([ QPointF(cx, cy), QPointF(fx, fy), QPointF(gx, gy), QPointF(hx, hy), QPointF(ix, iy) ])) painter.setPen(Qt.black) painter.drawPolyline( QPolygonF([QPointF(ax, ay), QPointF(ix, iy), QPointF(hx, hy)])) painter.drawPolyline( QPolygonF([QPointF(gx, gy), QPointF(fx, fy), QPointF(ex, ey)])) painter.drawPolyline( QPolygonF([QPointF(bx, by), QPointF(cx, cy), QPointF(dx, dy)]))
def paintEvent(self, event=None): font = QFont(self.font()) font.setPointSize(font.pointSize() - 1) # Returns -1 if the font size was specified in pixels. fm = QFontMetricsF(font) fracWidth = fm.width(FractionSlider.WSTRING) # 一个字母所占的宽度 indent = fm.boundingRect("9").width() / 2.0 # 半个字母的宽度 # Returns the bounding rectangle of the characters in the string specified by text. if not X11: fracWidth *= 1.5 span = self.width() - (FractionSlider.XMARGIN * 2) # 尺子的宽度 value = self.__numerator / float(self.__denominator) # 当前滑块的值 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # 设置抗锯齿 painter.setRenderHint(QPainter.TextAntialiasing) # 设置字体抗锯齿 painter.setPen(self.palette().color(QPalette.Midlight)) # setPen 可以接受Pen、PenStyle、Color对象 这里指的是Color # painter.setPen(QColor(220,100,100)) # 这里设置的是QWidght的边框 painter.setBrush(self.palette().brush( QPalette.AlternateBase)) # setBrush() : Sets the brush for the given color role to the specified brush for all groups in the palette. # [Color Role] QPalette.AlternateBase : Used as the alternate background color in views with alternating row colors # self.palette() This property holds the widget's palette 其会和默认的调色版混合呈现,但是其一般不能传递到窗口,需要特殊设置,推荐使用CSS painter.drawRect(self.rect()) segColor = QColor(Qt.gray).lighter(80) # 尺度条颜色:lighter(factor) 150表示50%亮,对于darker(factor) 300表示3倍暗 segLineColor = segColor.darker() # 默认200 lighter默认 150 painter.setPen(segLineColor) painter.setBrush(segColor) painter.drawRect(FractionSlider.XMARGIN, FractionSlider.YMARGIN, span, fm.height()) textColor = self.palette().color(QPalette.Text) segWidth = span / self.__denominator segHeight = fm.height() * 2 nRect = fm.boundingRect(FractionSlider.WSTRING) x = FractionSlider.XMARGIN yOffset = segHeight + fm.height() for i in range(self.__denominator + 1): painter.setPen(segLineColor) # 设置线的颜色作为Pen painter.drawLine(x, FractionSlider.YMARGIN, x, segHeight) # 划竖线,从(x,ymargin)开始,到(x,segheight)为止。 painter.setPen(textColor) y = segHeight rect = QRectF(nRect) rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) #painter.drawText(rect, Qt.AlignCenter, #QString.number(i)) painter.drawText(rect, Qt.AlignCenter,str(i)) y = yOffset rect.moveCenter(QPointF(x, y + fm.height() / 2.0)) painter.drawText(rect, Qt.AlignCenter, str(self.__denominator)) painter.drawLine(QPointF(rect.left() + indent, y), QPointF(rect.right() - indent, y)) x += segWidth span = int(span) y = FractionSlider.YMARGIN - 0.5 triangle = [QPointF(value * span, y), QPointF((value * span) + (2 * FractionSlider.XMARGIN), y), QPointF((value * span) + FractionSlider.XMARGIN, fm.height())] triangledict = (QPointF(value * span, y), QPointF((value * span) + (2 * FractionSlider.XMARGIN), y), QPointF((value * span) + FractionSlider.XMARGIN, fm.height())) painter.setPen(QColor(Qt.yellow).darker(100)) # painter.setBrush(Qt.darkYellow) painter.setBrush(QColor(Qt.yellow).darker(200)) painter.drawPolygon(QPolygonF(triangle))