Как нарисовать половину эллипса с вырезом в QPainter?

Как можно нарисовать такое с белой заливкой?:

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

import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush
from PyQt5.QtCore import Qt

a=20
b=22
d=8
s=2
m=6.5
l=round(a+b+s+m+0.3*d)
l0=22
ms=6

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):

        self.setGeometry(500, 300, 700, 600)
        #self.setWindowTitle('Pen styles')
        self.show()

    def paintEvent(self, e):

        qp = QPainter()
        #path = QPainterPath()
        qp.begin(self)
    
        self.drawBrushes(qp)
        self.bolt(qp)
        self.bolt_up(qp)
        self.drawLines(qp)
    
        qp.end()
    
    def bolt_up(self, qp):
        #qp.translate(500,-260)
        qp.setBrush(QColor('white'))
        qp.drawRect(210,300,180,200)
        qp.drawEllipse(275, 375, d*ms,d*ms)

        '''qp.drawPoint(299, 375-18.6) #up
        qp.drawPoint(299, 375+48+18.6) #down 
        qp.drawPoint(275-15, 375+24+24) #left_down
        qp.drawPoint(275-15, 375+24-24) #left_up
        qp.drawPoint(275+48+15, 375+24+24) #right_down
        qp.drawPoint(275+48+15, 375+24-24)'''

        qp.drawLine(299, round(375-18.6), 275-15, 375+24-24)
        qp.drawLine(299, round(375-18.6), 275+48+15, 375+24-24)
        qp.drawLine(275-15, 375+24-24, 275-15, 375+24+24)
        qp.drawLine(275-15, 375+24+24, 299, round(375+48+18.6))
        qp.drawLine(299, round(375+48+18.6), 275+48+15, 375+24+24)
        qp.drawLine(275+48+15, 375+24+24, 275+48+15, 375+24-24)

    def bolt(self, qp):
    
        brush = QBrush(QColor('white'))
        qp.setBrush(brush)
    
    
        qp.drawRect(210, 110, l*ms, d*ms) #длина и ширина болта
    
        qp.drawRect(210+l*ms,116, -l0*ms, 6*ms)
     #резьба
        qp.drawLine(210+(l-l0)*ms, 110, 210+(l-l0)*ms, d*ms+110)
    
        qp.drawRect(210+a*ms+b*ms+s*ms, 110,round( 6.5*ms), d*ms)
        qp.drawRect(210+a*ms+b*ms+s*ms, 92, round(6.5*ms), round(6.2/2*ms) )         #гайка
        qp.drawRect(210+a*ms+b*ms+s*ms, 158,round( 6.5*ms), round(6.2/2*ms))
   
  
        qp.drawRect(210+a*ms+b*ms, 97, s*ms, round(12.2*ms)) #шайба
    
    
    def drawBrushes(self, qp):
        qp.setBrush(QColor('white'))
        qp.drawEllipse(210-24, 80, 8*ms, 18*ms) #головка
    
        qp.drawRect(210, 35, a*ms, 200)
        qp.drawRect(210+a*ms, 35, b*ms, 200)
    
    
        brush = QBrush(Qt.BDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210, 35, a*ms, 200) #левый фланец

        brush.setStyle(Qt.FDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210+a*ms, 35, b*ms, 200) #правый фланец

    def drawLines(self, qp):
        pen = QPen( 5)

        pen.setStyle(Qt.DashDotLine)
     
        qp.setPen(pen)
        qp.drawLine(180, 135, 550, 135)
        qp.drawLine(190, 400,430,400)
        qp.drawLine(300,520,300,290)

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

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

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

Класс QPainterPath предоставляет контейнер для операций рисования, позволяющий создавать и повторно использовать графические фигуры.

Как вариант, примерно так:

import sys
from PyQt5.Qt import *


class MainWindow(QWidget):
    def __init__(self):
        super().__init__()  

        radius = 100
        square = QRectF(0, 0, 2*radius, 2*radius) 
      
        path = QPainterPath()
        path.moveTo(radius, 0)
        
        path.arcTo(square, 90, 80)   
        
        path.addRect(2, 82, 45, 1)        
        path.addRect(47, 82, 1, 40)
        path.addRect(2, 122, 45, 1)

        path.arcTo(square, 192, 78)
        
        path.addRect(100, 0, 1, 200)

        item = QGraphicsPathItem()
        item.setPen(QPen(Qt.red, 3, Qt.SolidLine)) 
        item.setPath(path)

        self.scene = QGraphicsScene()
        self.scene.addItem(item)

        self.view = QGraphicsView(self.scene, self)        
        self.view.setRenderHint(QPainter.Antialiasing) 
        
        vbox = QVBoxLayout(self)
        vbox.addWidget(self.view)


if __name__ == "__main__":    
    app = QApplication(sys.argv)
    w = MainWindow()
    w.resize(150, 300)
    w.show()
    sys.exit(app.exec_())

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

→ Ссылка
Автор решения: S. Nick

Добавил свой код, мне нужно такое же сделать, только вот с вырезом в полуэллипсе.

Вы спрашивали как нарисовать, а не как встроить рисование полуэллипса с вырезом в ваш код, который вы почему-то не предоставили. Поэтому если у вас возникают другие проблемы - вам надо задавать новый вопрос, а не изменять текущий.

import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtGui import QPainter, QColor, QPen, QBrush, QPainterPath
from PyQt5.QtCore import Qt, QRectF

a = 20
b = 22
d = 8
s = 2
m = 6.5
l = round(a + b + s + m + 0.3 * d)
l0 = 22
ms = 6


class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(500, 300, 700, 600)
        self.show()

    def paintEvent(self, e):
        qp = QPainter()
        #path = QPainterPath()
        qp.begin(self)
        self.drawBrushes(qp)
        self.bolt(qp)
        self.bolt_up(qp)
        self.drawLines(qp)
        qp.end()
    
    def bolt_up(self, qp):
        #qp.translate(500,-260)
        qp.setBrush(QColor('white'))
        qp.drawRect(210, 300, 180, 200)
        qp.drawEllipse(275, 375, d*ms,d*ms)
        qp.drawLine(299, round(375-18.6), 275-15, 375+24-24)
        qp.drawLine(299, round(375-18.6), 275+48+15, 375+24-24)
        qp.drawLine(275-15, 375+24-24, 275-15, 375+24+24)
        qp.drawLine(275-15, 375+24+24, 299, round(375+48+18.6))
        qp.drawLine(299, round(375+48+18.6), 275+48+15, 375+24+24)
        qp.drawLine(275+48+15, 375+24+24, 275+48+15, 375+24-24)

    def bolt(self, qp):
        brush = QBrush(QColor('white'))
        qp.setBrush(brush)
    
        qp.drawRect(210, 110, l*ms, d*ms)                          # длина и ширина болта
    
        qp.drawRect(210+l*ms,116, -l0*ms, 6*ms)
                                                                              # резьба
        qp.drawLine(210+(l-l0)*ms, 110, 210+(l-l0)*ms, d*ms+110)
    
        qp.drawRect(210+a*ms+b*ms+s*ms, 110,round( 6.5*ms), d*ms)
        qp.drawRect(210+a*ms+b*ms+s*ms, 92, round(6.5*ms), round(6.2/2*ms) )  # гайка
        qp.drawRect(210+a*ms+b*ms+s*ms, 158,round( 6.5*ms), round(6.2/2*ms))

        qp.drawRect(210+a*ms+b*ms, 97, s*ms, round(12.2*ms))                  # шайба

    def drawBrushes(self, qp):
        qp.setBrush(QColor('white'))
        
# !!! +++
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
#        qp.drawEllipse(210-24, 80, 8*ms, 18*ms)                             # головка

        square = QRectF(210-24, 80, 8*ms, 18*ms)   
      
        path = QPainterPath()
        path.moveTo(210, 125)              
        path.arcTo(square, 90, 80) 
        
        path.addRect(210-24, 125, 10, 0)
        path.addRect(210-24+10, 125, 0, 20)
        path.addRect(210-24, 145, 10, 0)

        path.arcTo(square, 192, 155)         
        
        qp.drawPath(path)

        pen = qp.pen()
        qp.setPen(QPen(Qt.GlobalColor.white))
        qp.drawRect(197, 125, 15, 20)
        qp.setPen(pen)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        qp.drawRect(210, 35, a*ms, 200)
        qp.drawRect(210+a*ms, 35, b*ms, 200)
   
        brush = QBrush(Qt.BDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210, 35, a*ms, 200) #левый фланец

        brush.setStyle(Qt.FDiagPattern)
        qp.setBrush(brush)
        qp.drawRect(210+a*ms, 35, b*ms, 200) #правый фланец

    def drawLines(self, qp):
        pen = QPen( 5)

        pen.setStyle(Qt.DashDotLine)
     
        qp.setPen(pen)
        qp.drawLine(180, 135, 550, 135)
        qp.drawLine(190, 400,430,400)
        qp.drawLine(300,520,300,290)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

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

→ Ссылка