Аналоговые часы, циферблат

У меня есть уже написанный виджет аналоговых часов. Мне нужно, чтобы на циферблате имелись цифры.

Может кто помочь пожалуйста, заранее спасибо.

class Clock(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        timer = QTimer(self)
        timer.timeout.connect(self.update)
        timer.start(1000)
        self.setStyleSheet('QWidget {Background-color: %s}' % QColor('black').name())
        self.setStyleSheet("background : black;")
        self.hPointer = QtGui.QPolygon([QPoint(6, 7),
                                        QPoint(-6, 7),
                                        QPoint(0, -50)])
        self.mPointer = QPolygon([QPoint(6, 7),
                                  QPoint(-6, 7),
                                  QPoint(0, -70)])
        self.bColor = Qt.green

    def paintEvent(self, e):
        painter = QPainter(self)
        rec = min(self.width(), self.height())
        tik = QTime.currentTime()

        def drawPointer(color, rotation, pointer):
            painter.setBrush(QBrush(color))
            painter.save()
            painter.rotate(rotation)
            painter.drawConvexPolygon(pointer)
            painter.restore()

        painter.setRenderHint(QPainter.Antialiasing)
        painter.translate(self.width() / 2, self.height() / 2)
        painter.scale(rec / 250, rec / 250)
        painter.setPen(QtCore.Qt.NoPen)
        drawPointer(self.bColor, (30 * (tik.hour() + tik.minute() / 60)), self.hPointer)
        drawPointer(self.bColor, (6 * (tik.minute() + tik.second() / 60)), self.mPointer)
        painter.setPen(QPen(self.bColor))
        for i in range(0, 60):
            if (i % 5) == 0:
                painter.drawLine(87, 0, 97, 0)
            painter.rotate(6)
        painter.end()
        self.update()

Ответы (1 шт):

Автор решения: S. Nick

Как вариант:

import sys
from datetime    import datetime
from PyQt5.QtGui     import QColor, QPalette, QBrush, QPixmap, \
    QPolygon, QPainter
from PyQt5.QtCore    import QPoint, QTimer, Qt
from PyQt5.QtWidgets import QWidget, QApplication, QAction


class Clock(QWidget):
    def __init__(self):
        super().__init__()
        
        pixmap = QPixmap("clock.png").scaled(291, 291, 
            Qt.KeepAspectRatio, Qt.FastTransformation)
        pal = self.palette()
        pal.setBrush(QPalette.Normal, QPalette.Window, QBrush(pixmap))
        pal.setBrush(QPalette.Inactive, QPalette.Window, QBrush(pixmap))
        self.setPalette(pal)
        self.setMask(pixmap.mask())        

        self.checktime()

        self.hourColor = QColor(127, 0, 127)
        self.minuteColor = QColor(0, 127, 127, 191)
        self.secondColor = QColor(127, 127, 0, 120)

        self.initUI()

        quitAction = QAction(
            "E&xit", 
            self, 
            shortcut="Ctrl+Q",
            triggered=self.close
        )
        self.addAction(quitAction)
        self.setContextMenuPolicy(Qt.ActionsContextMenu)

        self.timer = QTimer()
        self.timer.setInterval(1000)              
        self.timer.timeout.connect(self.update)
        self.timer.start()

    def handChange(self):
        self.side = min(self.width(), self.height())
        self.hand = (max(self.side/200,4), max(self.side/100,8), max(self.side/40,30))
        self.hourHand   = QPolygon([
            QPoint(self.hand[0], self.hand[1]),
            QPoint(-self.hand[0], self.hand[1]),
            QPoint(0, -self.hand[2])
        ])
        self.minuteHand = QPolygon([
            QPoint(self.hand[0], self.hand[1]),
            QPoint(-self.hand[0], self.hand[1]),
            QPoint(0, -self.hand[2]*1.6)
        ])
        self.secondHand = QPolygon([
            QPoint(self.hand[0], self.hand[1]),
            QPoint(-self.hand[0], self.hand[1]),
            QPoint(0, -self.hand[2]*1.6*1.6)
        ])

    def initUI(self):
        self.setFixedSize(291, 291)
        self.handChange()

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        self.draw(event, painter)
        painter.end()

    def draw(self, event, painter):
        self.checktime()
        painter.translate(self.width() / 2, self.height() / 2)
        painter.scale(self.side / 200.0, self.side / 200.0)

        painter.setPen(Qt.NoPen)
        painter.setBrush(self.hourColor)
        painter.save()
        painter.rotate(30.0 * ((self.time.hour + self.time.minute/ 60.0)))
        painter.drawConvexPolygon(self.hourHand)
        painter.restore()

        painter.setPen(Qt.NoPen)
        painter.setBrush(self.minuteColor)
        painter.save()

        painter.rotate(6.0 * ((self.time.minute + (self.time.second) / 60.0)))
        painter.drawConvexPolygon(self.minuteHand)
        painter.restore()

        painter.setPen(Qt.NoPen)
        painter.setBrush(self.secondColor)
        painter.save()
        painter.rotate(6.0 * (self.time.second))
        painter.drawConvexPolygon(self.secondHand)
        painter.restore()

    def checktime(self):
        self.time = datetime.now()
        self.hour = self.time.hour
        self.minute = self.time.minute
        self.second = self.time.second

    # Перетаскивание окна
    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.move(event.globalPos()-self.dragPos)
            event.accept()
            
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.dragPos=event.globalPos()-self.frameGeometry().topLeft()
            event.accept()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    clock  = Clock()
    clock.show()
    sys.exit(app.exec_())

введите сюда описание изображения

clock.png

введите сюда описание изображения



Update

Да, мне нужно именно по окружности цифры отрисовывать

import sys
import math
from PyQt5 import QtCore, QtGui, QtWidgets


class ClockWidget(QtWidgets.QWidget):
    L = 12
    r = 40.0
    DELTA_ANGLE = 2 * math.pi / L
    current_index = 9

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)

        R = min(self.rect().width(), self.rect().height()) / 2
        margin = 4

        Rect = QtCore.QRectF(0, 0, 2 * R - margin, 2 * R - margin)
        Rect.moveCenter(self.rect().center())

        painter.setBrush(QtGui.QColor("gray"))
        painter.drawEllipse(Rect)

        rect = QtCore.QRectF(0, 0, self.r, self.r)
        
        if 0 <= self.current_index < 12:
            c = self.center_by_index(self.current_index)
            rect.moveCenter(c)
            pen = QtGui.QPen(QtGui.QColor("red"))
            pen.setWidth(5)
            painter.setPen(pen)
            painter.drawLine(c, self.rect().center())
            painter.setBrush(QtGui.QColor("red"))
            painter.drawEllipse(rect)
# !!!
        for i in range(self.L):
            j = (i + 2) % self.L + 1
            c = self.center_by_index(i)
            rect.moveCenter(c)
            painter.setPen(QtGui.QColor("white"))
            painter.drawText(rect, QtCore.Qt.AlignCenter, str(j))
        
    def center_by_index(self, index):
        R = min(self.rect().width(), self.rect().height()) / 2
        angle = self.DELTA_ANGLE * index
        center = self.rect().center()
        return center + (R - self.r) * QtCore.QPointF(math.cos(angle), math.sin(angle))

    def index_by_click(self, pos):
        for i in range(self.L):
            c = self.center_by_index(i)
            delta = QtGui.QVector2D(pos).distanceToPoint(QtGui.QVector2D(c))
            if delta < self.r:
                return i
        return -1

    def mousePressEvent(self, event):
        i = self.index_by_click(event.pos())
        if i >= 0:
            self.current_index = i
            self.update()

    @property
    def hour(self):
        return (self.current_index + 2) % self.L + 1

    def minumumSizeHint(self):
        return QtCore.QSize(100, 100)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    view = ClockWidget()
    view.resize(400, 400)
    view.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка