一些背景
我正在尝试创建一个 QSplashScreen
带有自定义动画。我尝试了很多不同的方法,但都失败了。大多数情况下,我的主要技术是创建一个继承自 QSplashScreen
的新类。然后用 paintEvent()
进行计划。它起作用了……是的。动画不是问题,实际上是 QPaintDevice 似乎已损坏。
因为我正在调用super(classname, self).__init__(args)
只有在我的初始化并传递我在初始化中修改的参数之后,我总是有损坏的像素;图像色调怪异,背景中有彩色像素线。有时它是模式,有时它是完全随机的。
我尝试更改每一行代码,唯一删除这些行的是调用 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/