Add a circular progress bar to the manuscript build tool

This commit is contained in:
Veronica Berglyd Olsen
2023-06-07 22:37:47 +02:00
parent 3bcb4a5091
commit 4ee452d186
2 changed files with 85 additions and 13 deletions
@@ -0,0 +1,62 @@
"""
novelWriter Custom Widget: ProgressCircle
===========================================
File History:
Created: 2023-06-07 [2.1b1]
This file is a part of novelWriter
Copyright 20182023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from math import ceil
from PyQt5.QtGui import QPaintEvent, QPainter, QPen
from PyQt5.QtCore import QRect, Qt
from PyQt5.QtWidgets import QProgressBar, QSizePolicy, QWidget
class NProgressCircle(QProgressBar):
__slots__ = ("_mPx", "_bPen", "_cPen", "_cRect", "_tColor")
def __init__(self, parent: QWidget, size: int, point: int):
super().__init__(parent=parent)
self._mPx = point
self._bPen = QPen(self.palette().alternateBase(), point, Qt.SolidLine, Qt.RoundCap)
self._cPen = QPen(self.palette().highlight(), point, Qt.SolidLine, Qt.RoundCap)
self._cRect = QRect(point, point, size - 2*point, size - 2*point)
self._tColor = self.palette().text().color()
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.setFixedWidth(size)
self.setFixedHeight(size)
return
def paintEvent(self, event: QPaintEvent):
"""Custom painter for the progress bar."""
progress = 100.0*self.value()/self.maximum()
angle = ceil(16*3.6*progress)
qPaint = QPainter(self)
qPaint.setRenderHint(QPainter.Antialiasing, True)
qPaint.setPen(self._bPen)
qPaint.drawArc(self._cRect, 0, 360*16)
qPaint.setPen(self._cPen)
qPaint.drawArc(self._cRect, 90*16, -angle)
qPaint.setPen(self._tColor)
qPaint.drawText(self._cRect, Qt.AlignCenter, f"{progress:.1f} %")
return
# END Class NProgressCircle
+23 -13
View File
@@ -34,7 +34,7 @@ from PyQt5.QtGui import QColor, QCursor, QFont, QPalette, QResizeEvent
from PyQt5.QtCore import QSize, QTimer, Qt, pyqtSlot from PyQt5.QtCore import QSize, QTimer, Qt, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QDialog, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QMenu, QDialog, QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QMenu,
QProgressBar, QPushButton, QSplitter, QTextBrowser, QToolButton, QVBoxLayout, QWidget, QPushButton, QSplitter, QTextBrowser, QToolButton, QVBoxLayout, QWidget,
qApp qApp
) )
@@ -46,6 +46,7 @@ from novelwriter.core.docbuild import NWBuildDocument
from novelwriter.core.buildsettings import BuildCollection, BuildSettings from novelwriter.core.buildsettings import BuildCollection, BuildSettings
from novelwriter.tools.manusbuild import GuiManuscriptBuild from novelwriter.tools.manusbuild import GuiManuscriptBuild
from novelwriter.tools.manussettings import GuiBuildSettings from novelwriter.tools.manussettings import GuiBuildSettings
from novelwriter.extensions.circularprogress import NProgressCircle
if TYPE_CHECKING: # pragma: no cover if TYPE_CHECKING: # pragma: no cover
from novelwriter.guimain import GuiMain from novelwriter.guimain import GuiMain
@@ -143,14 +144,12 @@ class GuiManuscript(QDialog):
# Process Controls # Process Controls
# ================ # ================
self.buildProgress = QProgressBar() self.buildProgress = NProgressCircle(self, CONFIG.pxInt(140), CONFIG.pxInt(16))
self.buildProgress.setValue(0) self.buildProgress.setValue(0)
self.btnPreview = QPushButton(self.tr("Build Preview")) self.btnPreview = QPushButton(self.tr("Preview"))
self.btnPreview.clicked.connect(self._generatePreview) self.btnPreview.clicked.connect(self._generatePreview)
self.docPreview = _PreviewWidget(self.mainGui)
self.btnBuild = QPushButton(self.tr("Build")) self.btnBuild = QPushButton(self.tr("Build"))
self.btnBuild.clicked.connect(self._buildManuscript) self.btnBuild.clicked.connect(self._buildManuscript)
@@ -164,20 +163,28 @@ class GuiManuscript(QDialog):
self.btnClose = QPushButton(self.tr("Close")) self.btnClose = QPushButton(self.tr("Close"))
self.btnClose.clicked.connect(self._doClose) self.btnClose.clicked.connect(self._doClose)
self.buildBox = QVBoxLayout()
self.buildBox.addStretch(1)
self.buildBox.addWidget(self.btnPreview, 0)
self.buildBox.addWidget(self.btnPrint, 0)
self.buildBox.addWidget(self.btnBuild, 0)
self.buildBox.addWidget(self.btnClose, 0)
self.buildBox.addStretch(1)
self.buildBox.setSpacing(CONFIG.pxInt(2))
self.processBox = QHBoxLayout() self.processBox = QHBoxLayout()
self.processBox.addWidget(self.btnBuild) self.processBox.addWidget(self.buildProgress)
self.processBox.addWidget(self.btnPrint) self.processBox.addLayout(self.buildBox)
self.processBox.addWidget(self.btnClose)
# Assemble GUI # Assemble GUI
# ============ # ============
self.docPreview = _PreviewWidget(self.mainGui)
self.controlBox = QVBoxLayout() self.controlBox = QVBoxLayout()
self.controlBox.addLayout(self.listToolBox) self.controlBox.addLayout(self.listToolBox, 0)
self.controlBox.addWidget(self.buildList) self.controlBox.addWidget(self.buildList, 1)
self.controlBox.addWidget(self.buildProgress) self.controlBox.addLayout(self.processBox, 0)
self.controlBox.addWidget(self.btnPreview)
self.controlBox.addLayout(self.processBox)
self.controlBox.setContentsMargins(0, 0, 0, 0) self.controlBox.setContentsMargins(0, 0, 0, 0)
self.optsWidget = QWidget() self.optsWidget = QWidget()
@@ -186,6 +193,8 @@ class GuiManuscript(QDialog):
self.mainSplit = QSplitter() self.mainSplit = QSplitter()
self.mainSplit.addWidget(self.optsWidget) self.mainSplit.addWidget(self.optsWidget)
self.mainSplit.addWidget(self.docPreview) self.mainSplit.addWidget(self.docPreview)
self.mainSplit.setStretchFactor(0, 0)
self.mainSplit.setStretchFactor(1, 1)
self.mainSplit.setSizes([ self.mainSplit.setSizes([
CONFIG.pxInt(pOptions.getInt("GuiManuscript", "optsWidth", wWin//3)), CONFIG.pxInt(pOptions.getInt("GuiManuscript", "optsWidth", wWin//3)),
CONFIG.pxInt(pOptions.getInt("GuiManuscript", "viewWidth", 2*wWin//3)), CONFIG.pxInt(pOptions.getInt("GuiManuscript", "viewWidth", 2*wWin//3)),
@@ -288,6 +297,7 @@ class GuiManuscript(QDialog):
self.buildProgress.setMaximum(len(docBuild)) self.buildProgress.setMaximum(len(docBuild))
for step, status in docBuild.iterBuildHTML(None): for step, status in docBuild.iterBuildHTML(None):
self.buildProgress.setValue(step + 1) self.buildProgress.setValue(step + 1)
qApp.processEvents()
buildObj = docBuild.lastBuild buildObj = docBuild.lastBuild
assert isinstance(buildObj, ToHtml) assert isinstance(buildObj, ToHtml)