Round progress bar simplified and moved to Widgets

This commit is contained in:
Balthasar Reuter
2018-06-07 00:45:46 +02:00
parent 1d0a0186d1
commit b45dc7533b
3 changed files with 197 additions and 100 deletions

View File

@@ -120,7 +120,10 @@ class PyQt5Gui(Gui):
QtCore.QTimer.singleShot(cfg.getInt('Photobooth', 'greeter_time') * 1000, self.sendAck)
elif isinstance(state, CountdownState):
self._p.setCentralWidget(PyQt5CountdownMessage(cfg.getInt('Photobooth', 'countdown_time'), self.sendAck))
# self._p.setCentralWidget(PyQt5CountdownMessage(cfg.getInt('Photobooth', 'countdown_time'), self.sendAck))
countdown_time = cfg.getInt('Photobooth', 'countdown_time')
self._p.setCentralWidget(Frames.CountdownMessage(countdown_time,
self.sendAck))
elif isinstance(state, PreviewState):
self._p.centralWidget().picture = ImageQt.ImageQt(state.picture)
@@ -313,102 +316,3 @@ class PyQt5MainWindow(QtWidgets.QMainWindow):
def keyPressEvent(self, event):
self.handleKeypressEvent(event)
class PyQt5CountdownMessage(QtWidgets.QFrame):
def __init__(self, time, action):
super().__init__()
self._step_size = 50
self._counter = time * (1000 // self._step_size)
self._action = action
self._picture = None
self.initFrame()
self.initProgressBar(time)
def initFrame(self):
self.setStyleSheet('background-color: black; color: white;')
def initProgressBar(self, time):
self._bar = QRoundProgressBar()
self._bar.setBarStyle(QRoundProgressBar.StyleLine)
self._bar.setFixedSize(200, 200)
self._bar.setDataPenWidth(7)
self._bar.setOutlinePenWidth(10)
self._bar.setDecimals(0)
self._bar.setFormat('%v')
self._bar.setRange(0, time)
self._bar.setValue(time)
def updateProgressBar(self):
self._bar.setValue(self._counter / (1000 // self._step_size))
@property
def counter(self):
return self._counter
@property
def picture(self):
return self._picture
@picture.setter
def picture(self, pic):
if not isinstance(pic, QtGui.QImage):
raise ValueError('picture must be a QtGui.QImage')
self._picture = pic
def paintEvent(self, event):
painter = QtGui.QPainter(self)
if self._picture != None:
pix = QtGui.QPixmap.fromImage(self._picture)
pix = pix.scaled(self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.FastTransformation)
origin = ( (self.width() - pix.width()) // 2,
(self.height() - pix.height()) // 2 )
painter.drawPixmap(QtCore.QPoint(*origin), pix)
painter.end()
offset = ( (self.width() - self._bar.width()) // 2,
(self.height() - self._bar.height()) // 2 )
self._bar.render(self, QtCore.QPoint(*offset), self._bar.visibleRegion(), QtWidgets.QWidget.DrawChildren)
def showEvent(self, event):
self._timer = self.startTimer(self._step_size)
def timerEvent(self, event):
self._counter -= 1
if self._counter == 0:
self.killTimer(self._timer)
self._action()
else:
self.updateProgressBar()
self.update()

View File

@@ -13,6 +13,8 @@ from .. import modules
from ... import camera
from ... import printer
from . import Widgets
class Start(QtWidgets.QFrame):
@@ -222,6 +224,88 @@ class WaitMessage(QtWidgets.QFrame):
painter.end()
class CountdownMessage(QtWidgets.QFrame):
def __init__(self, time, action):
super().__init__()
self._step_size = 50
self._value = time * (1000 // self._step_size)
self._action = action
self._picture = None
self._initProgressBar(time)
def _initProgressBar(self, time):
self._bar = Widgets.RoundProgressBar(0, time, time)
self._bar.setFixedSize(200, 200)
def _updateProgressBar(self):
self._bar.value = self._value / (1000 // self._step_size)
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value
@property
def picture(self):
return self._picture
@picture.setter
def picture(self, picture):
if not isinstance(picture, QtGui.QImage):
raise ValueError('picture must be a QtGui.QImage')
self._picture = picture
def paintEvent(self, event):
# background image
if self.picture is not None:
painter = QtGui.QPainter(self)
pix = QtGui.QPixmap.fromImage(self.picture)
pix = pix.scaled(self.size(), QtCore.Qt.KeepAspectRatio,
QtCore.Qt.FastTransformation)
origin = ((self.width() - pix.width()) // 2,
(self.height() - pix.height()) // 2)
painter.drawPixmap(QtCore.QPoint(*origin), pix)
painter.end()
offset = ((self.width() - self._bar.width()) // 2,
(self.height() - self._bar.height()) // 2)
self._bar.render(self, QtCore.QPoint(*offset),
self._bar.visibleRegion(),
QtWidgets.QWidget.DrawChildren)
def showEvent(self, event):
self._timer = self.startTimer(self._step_size)
def timerEvent(self, event):
self.value -= 1
if self.value == 0:
self.killTimer(self._timer)
self._action()
else:
self._updateProgressBar()
self.update()
class Settings(QtWidgets.QFrame):
def __init__(self, config, reload_action, cancel_action, restart_action):

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from math import ceil
from PyQt5 import Qt
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtWidgets
class RoundProgressBar(QtWidgets.QWidget):
# Adaptation of QRoundProgressBar from
# https://sourceforge.net/projects/qroundprogressbar/
# to PyQt5, using the PyQt4-version offered at
# https://stackoverflow.com/a/33583019
def __init__(self, begin, end, value):
super().__init__()
self._begin = begin
self._end = end
self._value = value
self._data_pen_width = 7
self._outline_pen_width = 10
self._null_position = 90
@property
def value(self):
return self._value
@value.setter
def value(self, value):
if self._value != value:
if value < self._begin:
self._value = self._begin
elif value > self._end:
self._value = self._end
else:
self._value = value
def _drawBase(self, painter, base_rect):
color = self.palette().base().color()
color.setAlpha(100)
brush = self.palette().base()
brush.setColor(color)
painter.setPen(QtGui.QPen(self.palette().base().color(),
self._outline_pen_width))
painter.setBrush(brush)
painter.drawEllipse(base_rect.adjusted(self._outline_pen_width // 2,
self._outline_pen_width // 2,
-self._outline_pen_width // 2,
-self._outline_pen_width // 2))
def _drawCircle(self, painter, base_rect):
if self.value == self._begin:
return
arc_length = 360 / (self._end - self._begin) * self.value
painter.setPen(QtGui.QPen(self.palette().text().color(),
self._data_pen_width))
painter.setBrush(Qt.Qt.NoBrush)
painter.drawArc(base_rect.adjusted(self._outline_pen_width // 2,
self._outline_pen_width // 2,
-self._outline_pen_width // 2,
-self._outline_pen_width // 2),
self._null_position * 16, -arc_length * 16)
def _drawText(self, painter, inner_rect, inner_radius):
text = '{}'.format(ceil(self.value))
f = self.font()
f.setPixelSize(inner_radius * 0.8 / len(text))
painter.setFont(f)
painter.setPen(self.palette().text().color())
painter.drawText(inner_rect, Qt.Qt.AlignCenter, text)
def paintEvent(self, event):
outer_radius = min(self.width(), self.height())
inner_radius = outer_radius - self._outline_pen_width
delta = (outer_radius - inner_radius) / 2
base_rect = QtCore.QRectF(1, 1, outer_radius - 2, outer_radius - 2)
inner_rect = QtCore.QRectF(delta, delta, inner_radius, inner_radius)
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
# base circle
self._drawBase(painter, base_rect)
# data circle
self._drawCircle(painter, base_rect)
# text
self._drawText(painter, inner_rect, inner_radius)
painter.end()