Немного контекста
Я пытаюсь сделать QSplashScreen
с пользовательской анимацией.Я перепробовал много разных подходов, с каждым провалом.Главным образом, моей основной техникой было создание нового класса, который наследуется от QSplashScreen
, а затем планируется с paintEvent()
.Это сработало ... иш.Анимация не проблема, это действительно QPaintDevice, который кажется поврежденным.
Поскольку я вызывал super(classname, self).__init__(args)
единственный способ в моем init и передавал ему аргументы, которые я изменил в init, у меня всегда были поврежденные пиксели;Изображение было в странных тонах и имело линии разноцветных пикселей на заднем плане.Иногда это шаблоны, иногда они совершенно случайны.
Я пытался изменить каждую строку кода, и единственное, что удалило эти строки, это вызов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