I've a widget that is basically a circle. I want to draw it progressively so I need to draw it in steps (imo).
With the following code, I have achieved what I want. However, there's a problem. I'm passing a new event to the paintEvent
function, because if I don't, the image doesn't get updated until everything is finished, so I achieve nothing I wanted.
The widget code
import sys
import time
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox, QDesktopWidget
from PyQt5.QtGui import QPen, QPainter, QPaintEvent, QConicalGradient, QColor, QBrush
class Circle(QWidget):
def __init__(self, size, color):
super().__init__()
self.loadingAngle = 0
self.width = 0
self.color = color
self.pixmap_opacity = 1
self.resize(size, size);
self.center()
self.initUI()
def initUI(self):
self.width = 15
self.loadingAngle = 0
self.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def paintEvent(self, qevent):
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setStyleSheet("background:transparent;")
drawingRect = QRect()
drawingRect.setX(qevent.rect().x() + self.width)
drawingRect.setY(qevent.rect().y() + self.width)
drawingRect.setWidth(qevent.rect().width() - self.width * 2)
drawingRect.setHeight(qevent.rect().height() - self.width * 2)
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
gradient = QConicalGradient()
gradient.setCenter(drawingRect.center())
gradient.setAngle(90)
gradient.setColorAt(1, QColor(0,0,0))
gradient.setColorAt(0, QColor(self.color[0], self.color[1],self.color[2]))
arcLengthApproximation = self.width + self.width / 3
pen = QPen(QBrush(gradient), self.width)
pen.setCapStyle(Qt.RoundCap)
painter.setPen(pen)
painter.drawArc(drawingRect, 90 * 16 - arcLengthApproximation, -self.loadingAngle * 16)
#time.sleep(0.25)
if self.loadingAngle < 360:
self.loadingAngle += 1
#self.paintEvent(QDrawEvent())
self.paintEvent(QPaintEvent())
The problematic line
self.paintEvent(QPaintEvent())
This line produces several errors, but even with them, I does what I want.
If I pass the
qevent
from the function itself to this new call, the image doesn't get updated as I said before.If I create this new
QPaintEvent
, it does work. However, the errors are:
Traceback (most recent call last):
File "/home/btc/Escritorio/SinestesiaRCB/Clases/Widget.py", line 68, in paintEvent self.paintEvent(QPaintEvent())
TypeError: arguments did not match any overloaded call: QPaintEvent(QRegion): not enough arguments
QPaintEvent(QRect): not enough arguments
QPaintEvent(QPaintEvent): not enough arguments
QBackingStore::endPaint() called with active painter on backingstore paint device
These errors may be comming from the other lines like:
qevent.rect().x()
Since the new event is an empty one.
So basically my question is, how should I do it to make it correctly, meaning achieve what I want without errors?
PS. What I mean by progressively. This has been done creating several widgets, one second after the former each one.