def drawText(self, painter: QPainter, index: int, offset: int) -> None: painter.save() width: int = self.width() height: int = self.height() strValue: str = str(self.__listValue[index]) target: int = width if self.__horizontal else height font: QFont = painter.font() font.setPixelSize((target - abs(offset)) // 8) painter.setFont(font) if self.__horizontal: textWidth: int = painter.fontMetrics().width(strValue) initX: int = width // 2 + offset - textWidth // 2 painter.drawText(QRect(initX, 0, textWidth, height), Qt.AlignCenter, strValue) # 计算最后中间值停留的起始坐标,以便鼠标松开时矫正居中 if index is self.__currentIndex: self.__currentPos = initX else: textHeight: int = painter.fontMetrics().height() initY: int = height // 2 + offset - textHeight // 2 painter.drawText(QRect(0, initY, width, textHeight), Qt.AlignCenter, strValue) # 计算最后中间值停留的起始坐标,以便鼠标松开时矫正居中 if index is self.__currentIndex: self.__currentPos = initY painter.restore()
def drawText(self, painter: QPainter) -> None: """ """ painter.save() textFont: QFont = QFont() textFont.setBold(True) painter.setFont(textFont) count: int = len(self.__listItem) self.__initLen = 0 # 横向导航时,字符区域取条目元素中最长的字符宽度 longText: str = "" for item in self.__items.split("|"): if len(item) > len(longText): longText = item if self.horizontal: textLen: Decimal = Decimal(painter.fontMetrics().width(longText)) else: textLen: Decimal = Decimal(painter.fontMetrics().height()) # 逐个绘制元素列表中的文字及文字背景 for i in range(count): strText: str = self.__listItem[i][0] left: QPointF = QPointF(self.__initLen, 0) right: QPointF = QPointF(self.__initLen + textLen + self.__space, self.height()) if not self.horizontal: left = QPointF(0, self.__initLen) right = QPointF(self.width(), self.__initLen + textLen + self.__space) textRect: QRectF = QRectF(left, right) self.__listItem[i][1] = textRect if self.__isVirgin: self.__barRect = textRect self.__isVirgin = False # 当前选中区域的文字显示选中文字颜色 if textRect == self.__listItem[self.__currentIndex][1]: painter.setPen(self.__textSelectColor) else: painter.setPen(self.__textNormalColor) painter.drawText(textRect, Qt.AlignCenter, strText) self.__initLen += textLen + self.__space painter.restore()
def _paintEvent(self, event): super().paintEvent(event) painter = QPainter(self) fontMetrics = painter.fontMetrics() lineSpacing = self.fontMetrics().lineSpacing() y = 0 textLayout = QTextLayout(self._content, painter.font()) textLayout.setTextOption(self._textOption) textLayout.beginLayout() while True: line = textLayout.createLine() if not line.isValid(): break line.setLineWidth(self.width()) nextLineY = y + lineSpacing if self.height() >= nextLineY + lineSpacing: # not the last line elidedLine = self._content[line.textStart():line.textStart() + line.textLength()] elidedLine = fontMetrics.elidedText(elidedLine, self._elideMode, self.width()) painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLine) y = nextLineY else: # last line, check if we are to elide here to the end lastLine = self._content[line.textStart():] elidedLastLine = fontMetrics.elidedText(lastLine, self._elideMode, self.width()) painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine) break textLayout.endLayout()
def customPrint(printer, doc): painter = QPainter(printer) doc.documentLayout().setPaintDevice(printer) doc.setPageSize(printer.pageRect().size()) pageSize = printer.pageRect().size() tm = mmToPixels(printer, textMargins) footHeight = painter.fontMetrics().height() textRect = QRectF(tm, tm, pageSize.width() - 2 * tm, pageSize.height() - 2 * tm - footHeight) doc.setPageSize(textRect.size()) pagecount = doc.pageCount() for index in range(pagecount): if index != 0: printer.newPage() paintPage(index, pagecount, painter, doc, textRect, footHeight)
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): view = next(iter(self.scene().views())) painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setFont(self.font) painter.setPen(self.pen) fm = painter.fontMetrics() painter.drawLine(self.line) if not self.line.p1().isNull(): pen = QtGui.QPen(self.pen) pen.setWidth(10) painter.setPen(pen) painter.drawPoints([self.line.p1(), self.line.p2()]) painter.setPen(self.pen) if view is not None and self.text != "": angle = self.line.angle() if 90 < angle < 270: angle -= 180 center = view.mapFromScene(self.line.center()) length = ( view.mapFromScene(QtCore.QRectF(0, 0, self.line.length(), 1)) .boundingRect() .width() ) width = fm.boundingRect(self.text).width() if width < length * 0.9: painter.save() painter.resetTransform() transform = QtGui.QTransform() transform.translate(center.x(), center.y()) transform.rotate(-angle) painter.setTransform(transform) painter.drawText(-width / 2.0, -fm.descent(), self.text) painter.restore()
def paintEvent(self, event): painter = QPainter(self) painter.fillRect(self.rect(), Qt.black) if self.pixmap.isNull(): painter.setPen(Qt.white) painter.drawText(self.rect(), Qt.AlignCenter, "Rendering initial image, please wait...") return if self.curScale == self.pixmapScale: painter.drawPixmap(self.pixmapOffset, self.pixmap) else: scaleFactor = self.pixmapScale / self.curScale newWidth = int(self.pixmap.width() * scaleFactor) newHeight = int(self.pixmap.height() * scaleFactor) newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2 newY = self.pixmapOffset.y() + (self.pixmap.height() - newHeight) / 2 painter.save() painter.translate(newX, newY) painter.scale(scaleFactor, scaleFactor) exposed, _ = painter.matrix().inverted() exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1) painter.drawPixmap(exposed, self.pixmap, exposed) painter.restore() text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \ "hold left mouse button to scroll." metrics = painter.fontMetrics() textWidth = metrics.width(text) painter.setPen(Qt.NoPen) painter.setBrush(QColor(0, 0, 0, 127)) painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5) painter.setPen(Qt.white) painter.drawText((self.width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text)
def paint( self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget: QtWidgets.QWidget = None, ): super().paint(painter, option, widget) if self.isSelected(): painter.fillRect(self.rect(), QtGui.QBrush(QtGui.QColor(255, 255, 255, 32))) painter.setFont(self.font) fm = painter.fontMetrics() pos = QtCore.QPointF(self.rect().left(), self.rect().top()) pos = painter.transform().map(pos) painter.save() painter.resetTransform() painter.setPen(self.pen()) painter.drawText(pos.x() + 5, pos.y() + fm.ascent(), self.label) painter.restore()
def paintEvent(self, event): """ standard qt paint event :param event: a QPaintEvent instance :return: """ super().paintEvent(event) painter = QPainter(self) try: fontMetrics = painter.fontMetrics() lineSpacing = self.fontMetrics().lineSpacing() y = 0 textLayout = QTextLayout(self._content, painter.font()) textLayout.setTextOption(self._textOption) textLayout.beginLayout() while True: line = textLayout.createLine() if not line.isValid(): break line.setLineWidth(self.width()) nextLineY = y + lineSpacing if self.height() >= nextLineY + lineSpacing: # not the last line elidedLine = self._content[line.textStart():line.textStart() + line.textLength()] elidedLine = fontMetrics.elidedText(elidedLine, self._elideMode, self.width()) painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLine) y = nextLineY else: # last line, check if we are to elide here to the end lastLine = self._content[line.textStart():] elidedLastLine = fontMetrics.elidedText(lastLine, self._elideMode, self.width()) painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine) break textLayout.endLayout() except Exception as e: logger.exception("Exception during paint: %s", e)
class TypingWindow(QMainWindow): def __init__(self, parent=None): super(TypingWindow, self).__init__(parent=parent) # TODO: Implement themes system self.config = { 'error_color': QColor(255, 190, 190), 'done_color': QColor(190, 255, 190), 'secondary_color': QColor(230, 230, 230), 'background_color': QColor(255, 255, 255), 'primary_color': QColor(34, 34, 34), 'dictionary': english_words_set } self.setupWindow() self.settings = QSettings(QCoreApplication.applicationName(), parent=self) self.reset() def paintEvent(self, event): self.painter = QPainter() self.painter.begin(self) # Limiting the font size to 32 self.painter.setFont( QFont( 'Menlo', max( 32, event.rect().height() / self.settings.value('fontFactor', 6)))) self.isEnd = self.pointer >= len(self.text) # Calculating line properties letterSize = self.painter.fontMetrics() textY = event.rect().height() / 2 + letterSize.height() / 4 lineColor = self.config['done_color'] if self.isEnd else ( self.config['error_color'] if len(self.events) > 0 and not self.events[-1]['correct'] else self.config['secondary_color']) lineWidth = letterSize.maxWidth() + self.settings.value( 'linePadding', 10) linePadding = event.rect().width() / 4 lineX = linePadding if not self.settings.value( 'enableSliding', False) else linePadding + ( ((event.rect().width() - lineWidth) - (linePadding * 2)) / len(self.text)) * self.pointer # Rendering line self.painter.setPen(QPen(lineColor, 1, Qt.SolidLine)) self.painter.setBrush(QBrush(lineColor, Qt.SolidPattern)) self.painter.drawRect(lineX, 0, lineWidth, event.rect().height()) # Primary Text if not self.isEnd: self.painter.setPen(self.config['primary_color']) self.painter.drawText( lineX + self.settings.value('linePadding', 10) / 2, textY, self.text[self.pointer]) self.painter.drawText( lineX + lineWidth + self.settings.value('linePadding', 10) / 2, textY, self.text[self.pointer + 1:]) if len(self.events) > 1: speed = round(60 / mean([ event['time'] - self.events[self.events.index(event) - 1]['time'] for event in self.events[1:] ])) typos = len( [event for event in self.events if not event['correct']]) print('{} char/min, {} typos'.format(speed, typos)) # TODO: Implement result screen # and draw next text starting on the right # Typed Text typedTextSize = self.painter.fontMetrics().size( Qt.TextSingleLine, self.text[:self.pointer]) self.painter.setPen(self.config['secondary_color']) self.painter.drawText( lineX - typedTextSize.width() - self.settings.value('linePadding', 10) / 2, textY, self.text[:self.pointer]) self.painter.end() def keyPressEvent(self, event) -> None: if event.key() == Qt.Key_Return: self.reset() elif self.settings.value( 'enableBackspace', True) and event.key() == Qt.Key_Backspace and self.pointer > 0: self.pointer -= 1 elif event.key() not in [ord(char) for char in printable] or self.isEnd: return else: isCorrect = event.text() == self.text[self.pointer] self.events.append({ 'key': event.text(), 'pointer': self.pointer, 'correct': isCorrect, 'time': time() }) self.pointer += 1 self.repaint() def reset(self) -> None: self.events = [] self.text = ' '.join([ choice(list(self.config['dictionary'])).lower() for _ in range(self.settings.value('wordsCount', 20)) ]) self.pointer = 0 def setupWindow(self) -> None: self.setWindowTitle('Typetific') self.setMinimumSize(1100, 620) self.setUnifiedTitleAndToolBarOnMac(True) self.setStyleSheet('background: {}; color: {};'.format( self.config['background_color'].name(), self.config['primary_color'].name()))
class Display_area(QWidget): displays = [] size = (800, 600) coord = np.array((50, 50)) decalage = np.array((40, 40)) def __init__( self, subject, center, ech, ): super(plot_graph.Display_area, self).__init__() app = QApplication.instance() if not app: app = QApplication(sys.argv) desktop = app.desktop() screen = desktop.screenGeometry(desktop.screenNumber(self)) self.radius = 4 self.ech = ech self.center = np.array(center) self.cradius = None self.subject = subject self.setStyleSheet('background-color: grey') self.center = np.array(plot_graph.Display_area.size) / 2. self.setGeometry(plot_graph.Display_area.coord[0] + screen.x(), plot_graph.Display_area.coord[1] + screen.y(), plot_graph.Display_area.size[0], plot_graph.Display_area.size[1]) plot_graph.Display_area.coord += plot_graph.Display_area.decalage self.show() def __pointToPixel(self, p): p = np.array(p) pixel = (p - self.center) * self.ech # pixel = p * self.ech pixel[1] = -pixel[1] pixel += self.center return qtcore.QPoint(pixel[0], pixel[1]) def __pixelToPoint(self, pixel): p = np.array((pixel.x(), pixel.y())) - self.center p[1] = -p[1] p = p / self.ech + self.center return p def __pixelToVector(self, pixel1, pixel2): v = np.array((pixel2.x(), pixel2.y())) - np.array( (pixel1.x(), pixel1.y())) v[1] = -v[1] v = v / self.ech return v def tracePoint(self, p): pixel = self.__pointToPixel(p) self.cradius.drawEllipse(pixel, self.radius, self.radius) def addLine(self, p1, p2): pixel1 = self.__pointToPixel(p1) pixel2 = self.__pointToPixel(p2) self.cradius.drawLine(pixel1, pixel2) def changecolor(self, color): c = QColor(color[0] * 255, color[1] * 255, color[2] * 255) self.cradius.setPen(c) self.cradius.setBrush(c) def traceText(self, p, text): pixel = self.__pointToPixel(p) pixel += qtcore.QPoint(10, -10) self.cradius.drawText(pixel, text) def rename(self, title): self.setWindowTitle(title) def mousePressEvent(self, QMouseEvent): pos = QMouseEvent.pos() self.clic = pos pos = self.__pixelToPoint(pos) self.center = self.center def mouseMoveEvent(self, QMouseEvent): pos = QMouseEvent.pos() self.center -= self.__pixelToVector(self.clic, pos) self.clic = pos self.update() def mouseReleaseEvent(self, QMouseEvent): pos = QMouseEvent.pos() self.center -= self.__pixelToVector(self.clic, pos) self.clic = pos self.update() def wheelEvent(self, event): pos = event.pos() C = self.__pixelToPoint(pos) k1 = self.ech k2 = k1 * math.exp(0.001 * event.delta()) self.center = (self.center * k1 + C * (k2 - k1)) / k2 self.ech = k2 self.update() def paintEvent(self, event): if self.cradius != None: return self.cradius = QPainter(self) self.trace() self.cradius = None def trace(self): self.cradius.setFont(QFont('Decorative', 10)) if self.subject != None: self.subject.trace(self) L = 100 x = 20 y = 20 self.cradius.setPen('white') msg = '{0:.2f} km'.format(L / self.ech) l = self.cradius.fontMetrics().boundingRect(msg).width() self.cradius.drawText(x + (L - l) / 2, y - 2, msg) self.cradius.drawLine(x, y, x + L, y) self.cradius.drawLine(x, y - L / 20, x, y + L / 10) self.cradius.drawLine(x + L, y - L / 20, x + L, y + L / 10) def save(self): filename = QFileDialog.getSaveFileName(self, 'PDF file') if filename: printer = QPrinter(QPrinter.HighResolution) printer.setPageSize(QPrinter.A4) printer.setColorMode(QPrinter.Color) printer.setOutputFormat(QPrinter.PdfFormat) printer.setOutputFileName(filename) self.cradius = QPainter(printer) self.trace() self.cradius = None