PyQt5 – 将图像条作为进度条

  • Post category:Python

下面是关于PyQt5如何实现将图像条作为进度条的详细使用攻略。

简介

PyQt5是一个用于构建GUI应用程序的Python库,而将图像条作为进度条则是一种定制化进度条的方式。这种方式可以改变原有的进度条样式,使进度条更加具有吸引力。

实现过程

  1. 使用QProgressBar控件

首先,需要使用PyQt5中的QProgressBar控件来创建进度条。在创建进度条的时候,可以先设置进度条的样式为无边框,如下:

progressBar = QProgressBar(self)
progressBar.setGeometry(0, 0, 200, 30)
progressBar.setStyleSheet("""
    QProgressBar {
        background-color: transparent;
        color: white;
        text-align: center;
        font-weight: bold;
    }

    QProgressBar::chunk {
        background-color: #0080FF;
    }
""")

可以看到,这里将进度条的样式设置为了无边框,同时通过CSS样式来设置了进度条的颜色和字体样式等。

  1. 自定义进度条图片

其次,需要使用图片来作为进度条,这里我们可以使用QPixmap来加载图片,如下:

pixmap = QPixmap("progress_bar.png")
pixmap = pixmap.scaled(progressBar.width(), progressBar.height())

通过QPixmap的scaled方法,可以将图片按照进度条的大小进行缩放。

  1. 显示图片

最后,需要将图片显示到进度条上,这里可以使用QPainter类。代码如下:

painter = QPainter(self)
painter.drawPixmap(0, 0, pixmap)

通过QPainter的drawPixmap方法,可以将图片绘制在进度条上。

完整代码如下:

from PyQt5.QtWidgets import QMainWindow, QApplication, QProgressBar
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtCore import Qt
import sys

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

        self.setGeometry(100, 100, 300, 200)

        progressBar = QProgressBar(self)
        progressBar.setGeometry(0, 0, 200, 30)
        progressBar.setStyleSheet("""
            QProgressBar {
                background-color: transparent;
                color: white;
                text-align: center;
                font-weight: bold;
            }

            QProgressBar::chunk {
                background-color: #0080FF;
            }
        """)

        pixmap = QPixmap("progress_bar.png")
        pixmap = pixmap.scaled(progressBar.width(), progressBar.height())

        self.progress = 0

        self.timer = self.startTimer(100)

    def timerEvent(self, event):
        self.progress += 1

        if self.progress > 100:
            self.timer.stop()
            self.timer = None
            return

        self.repaint()

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

        pixmap = QPixmap("progress_bar.png")
        pixmap = pixmap.scaled(self.width(), self.height())

        painter.drawPixmap(0, 0, pixmap)

        painter.setCompositionMode(QPainter.CompositionMode_SourceIn)

        progressPixmap = pixmap.copy(0, 0, self.progress * pixmap.width() // 100, pixmap.height())

        if progressPixmap.isNull() == False:
            painter.drawPixmap(0, 0, progressPixmap)

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

示例说明

现在我们通过两个示例来具体说明如何使用PyQt5将图像条作为进度条。

示例1:将图片作为进度条

这里使用的是一张图片来作为进度条,图片随着进度的增加而逐渐填满。代码如下:

from PyQt5.QtWidgets import QMainWindow, QApplication, QProgressBar
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtCore import Qt
import sys

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

        self.setGeometry(100, 100, 300, 200)

        progressBar = QProgressBar(self)
        progressBar.setGeometry(0, 0, 200, 30)
        progressBar.setStyleSheet("""
            QProgressBar {
                background-color: transparent;
                color: white;
                text-align: center;
                font-weight: bold;
            }

            QProgressBar::chunk {
                background-color: #0080FF;
            }
        """)

        pixmap = QPixmap("progress_bar.png")
        pixmap = pixmap.scaled(progressBar.width(), progressBar.height())

        self.progress = 0

        self.timer = self.startTimer(100)

    def timerEvent(self, event):
        self.progress += 1

        if self.progress > 100:
            self.timer.stop()
            self.timer = None
            return

        self.repaint()

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

        pixmap = QPixmap("progress_bar.png")
        pixmap = pixmap.scaled(self.width(), self.height())

        painter.drawPixmap(0, 0, pixmap)

        painter.setCompositionMode(QPainter.CompositionMode_SourceIn)

        progressPixmap = pixmap.copy(0, 0, self.progress * pixmap.width() // 100, pixmap.height())

        if progressPixmap.isNull() == False:
            painter.drawPixmap(0, 0, progressPixmap)

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

示例2:将多张图片组成的动画作为进度条

这里使用了多张图片组成的动画,实现了一个更加生动有趣的进度条。代码如下:

from PyQt5.QtWidgets import QMainWindow, QApplication, QProgressBar
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtCore import Qt
import sys

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

        self.setGeometry(100, 100, 300, 200)

        progressBar = QProgressBar(self)
        progressBar.setGeometry(0, 0, 200, 30)
        progressBar.setStyleSheet("""
            QProgressBar {
                background-color: transparent;
                color: white;
                text-align: center;
                font-weight: bold;
            }

            QProgressBar::chunk {
                background-color: transparent;
            }
        """)

        self.pixmaps = []
        for i in range(1, 7):
            pixmap = QPixmap("progress_bar_{0}.png".format(i))
            pixmap = pixmap.scaled(QSize(200, 30))
            self.pixmaps.append(pixmap)

        self.progress = 0

        self.timer = self.startTimer(100)

    def timerEvent(self, event):
        self.progress += 1

        if self.progress > 100:
            self.timer.stop()
            self.timer = None
            return

        self.repaint()

    def paintEvent(self, event):
        progressPixmap = self.pixmaps[self.progress % len(self.pixmaps)]

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setRenderHint(QPainter.SmoothPixmapTransform)

        pixmap = QPixmap("progress_bar_bg.png")
        pixmap = pixmap.scaled(self.width(), self.height())

        painter.drawPixmap(0, 0, pixmap)
        painter.drawPixmap(0, 0, progressPixmap)

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

这里有一些需要注意的地方。首先,不同的图片大小可能会不同,因此需要对其进行适当的缩放。其次,在运行过程中需要不断地更新进度条的图片,这可以通过获取当前进度条位置和图片数量取余得到。