python - 初始化后扩大QPaintDevice的大小

标签 python pyqt splash-screen qpainter

一些背景

我正在尝试创建一个 QSplashScreen带有自定义动画。我尝试了很多不同的方法,但都失败了。大多数情况下,我的主要技术是创建一个继承自 QSplashScreen 的新类。然后用 paintEvent() 进行计划。它起作用了……是的。动画不是问题,实际上是 QPaintDevice 似乎已损坏。

因为我正在调用super(classname, self).__init__(args)只有在我的初始化并传递我在初始化中修改的参数之后,我总是有损坏的像素;图像色调怪异,背景中有彩色像素线。有时它是模式,有时它是完全随机的。

enter image description here

我尝试更改每一行代码,唯一删除这些行的是调用 super()__init__开头。不幸的是,我正在制作一个传递给 init 的框架。既然这是不可能的,我想修改 QPaintDevice 的大小我的QSplashScreen初始化,因为我的动画显示在该帧之外。我不会发布所有代码,因为自定义动画相当繁重。

最小工作示例

from PyQt5.QtWidgets import QApplication, QSplashScreen, QMainWindow
from PyQt5.QtCore import Qt, QSize, pyqtSignal, QPoint
from PyQt5.QtGui import QPixmap, QPainter, QIcon, QBrush
import time, sys


class FakeAnimatedSplash(QSplashScreen):
    def __init__(self, image):
        self.image = image
        self.newFrame = QPixmap(self.image.size()+QSize(0, 20))
        super(FakeAnimatedSplash, self).__init__(self.newFrame, Qt.WindowStaysOnTopHint)

    def showEvent(self, event):
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.transparent)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setPen(Qt.NoPen)
        painter.drawPixmap(self.image.rect(), self.image)
        painter.drawEllipse(QPoint(0, 110), 8, 8)


class App(QApplication):
    def __init__(self, sys_argv):
        super(App, self).__init__(sys_argv)
        self.main = QMainWindow()
        self.setAttribute(Qt.AA_EnableHighDpiScaling)
        self.newSplash()
        self.main.show()

    def newSplash(self):
        pixmap = QPixmap("yourImage.png")
        smallerPixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.SmoothTransformation)
        splash = FakeAnimatedSplash(smallerPixmap)
        splash.setEnabled(False)
        splash.show()
        start = time.time()
        while time.time() < start + 10:
            self.processEvents()


def main():
    app = App(sys.argv)
    app.setWindowIcon(QIcon("ABB_icon.png"))
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

潜在的解决方案

更改 super()到开始使其工作,但减少了隐藏我的动画的 QPaintDevice 窗口。我想扩展它,但初始化后没有方法可以做到这一点。

    def __init__(self, image):
        super(LoadingDotsSplash, self).__init__(image, QtCore.Qt.WindowStaysOnTopHint)
        self.image = image
        # here a function or method that changes the size of the QPaintDevice

最佳答案

问题是 newFrame 是一个未初始化的 QPixmap,出于效率原因,像素不会被修改,因此它们具有随机值,这是因为 FakeAnimatedSplash 的大小大于绘制的 QPixmap。解决方案是将newFrame像素的值设置为透明:

class FakeAnimatedSplash(QSplashScreen):
    def __init__(self, image):
        self.image = image
        pix = QPixmap(self.image.size() + QSize(0, 20))
        pix.fill(Qt.transparent)
        super(FakeAnimatedSplash, self).__init__(pix, Qt.WindowStaysOnTopHint)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.transparent)
        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.setPen(Qt.NoPen)
        painter.drawPixmap(self.image.rect(), self.image)
        painter.drawEllipse(QPoint(0, 110), 8, 8)

关于python - 初始化后扩大QPaintDevice的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56551236/

相关文章:

python - 如何在pyqt中创建模态窗口?

适用于所有设备的 jQuery Mobile 初始屏幕

android - 删除 PWA 初始屏幕中的名称

Android:有关初始屏幕图像最佳尺寸的帮助

python - Networkx - 如何从 "all_pairs_shortest_path_length"函数中获取值(value)?

python - 模板中的删除按钮处于非事件状态

python - PySide 自定义选项卡

python - 从椭圆生成数组

python - 在 PyQt 中创建和使用用户定义的槽

python - 使用pyqt webview渲染pdf