我正在尝试使用自定义动画制作QSplashScreen
。我尝试了许多不同的方法,每次失败。通常,我的主要技术是创建一个继承自QSplashScreen
的新类,然后使用paintEvent()
进行计划。它奏效了。动画不是问题,实际上是QPaintDevice似乎已损坏。
因为我在初始化后仅调用super(classname, self).__init__(args)
,并将在初始化时修改过的参数传递给它,所以我总是损坏像素;图像色调怪异,背景中有彩色像素线条。有时是模式,有时是完全随机的。
{{3}}
我尝试过更改每一行代码,唯一删除这些行的是在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
答案 0 :(得分:1)
问题是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)