0

I am trying to create a GUI application in python using PyQt5 and wanted to implement splash screen in it. The problem is that after hiding the splash screen image I add a button to the same QWidget and call update() but it isn't showing.

Code

import sys
from PyQt5.QtWidgets import QApplication, QLabel, QWidget,QPushButton
from PyQt5.QtGui import QCursor,QPixmap
from PyQt5.QtCore import Qt,QTimer

class classer:
   def __init__(self):
      self.w=QWidget()
      self.w.setFixedSize(640,480)
      self.w.setWindowTitle("Classer")

   def splashScreen(self):
      img = QLabel(self.w)
      img.setGeometry(0,0,640,480)
      pixmap = QPixmap('SplashScreen.png')
      img.setPixmap(pixmap.scaled(640,480,Qt.KeepAspectRatio))
      self.w.show()
      QTimer.singleShot(2000, img.hide)

   def mainScreen(self):
      btn=QPushButton(self.w)
      btn.setText('Click')
      btn.move(270,228)
      btn.setCursor(QCursor(Qt.PointingHandCursor))
      self.w.update()
      print("reached here!")

   def run(self):
      self.splashScreen()
      self.mainScreen()
      sys.exit(app.exec_())
    
if __name__ == '__main__':
   app = QApplication([])
   app.setStyleSheet(open('StyleSheet.css').read())
   instance=classer()
   instance.run()

Splash Screen

enter image description here

Current state after hiding image and calling .update()

enter image description here

Desired state after hiding image and calling .update()

enter image description here

Community
  • 1
  • 1
Neeraj Kumar
  • 515
  • 7
  • 18
  • 1
    i think you just miss `btn.show()` ? – PRMoureu Jul 20 '19 at 12:01
  • Using btn.show() explicitly will paint the button at the start of the application itself over the splash screen. That is not desired. – Neeraj Kumar Jul 20 '19 at 12:06
  • 1
    then you can create a method to plug to the `singleShot` that will hide `img` and show `btn`. (may be handy to keep a reference to them --> `self.img` and `self.btn`) – PRMoureu Jul 20 '19 at 12:10
  • 2
    or simpler : juste launch `self.mainScreen()` before `self.splashScreen()` – PRMoureu Jul 20 '19 at 12:17

1 Answers1

3

The method update will only work on visible widgets (doc), and the QPushButton is not visible since the w.show() method is called before the button creation. So you don't really need update here.

You can achieve this by moving some lines, like below :

   def splashScreen(self):
      img = QLabel(self.w)
      img.setGeometry(0,0,640,480)
      pixmap = QPixmap('background.png')
      img.setPixmap(pixmap.scaled(640,480,Qt.KeepAspectRatio))    
      QTimer.singleShot(2000, img.hide)

   def mainScreen(self):
      btn=QPushButton(self.w)
      btn.setText('Click')
      btn.move(270,228)
      btn.setCursor(QCursor(Qt.PointingHandCursor))

   def run(self):    
      self.mainScreen()   # --> paint the button
      self.splashScreen() # --> paint the img on top layer
      self.w.show()       # --> display the widget

It's better to keep self.w.show() outside splashScreen, the whole widget will not depend on the splash display (in case you want to comment self.splashScreen() to save 2sec each time you run the program, for example).

PRMoureu
  • 12,817
  • 6
  • 38
  • 48
  • 1
    Cool ! But why isn't .update( ) working in this case though? – Neeraj Kumar Jul 20 '19 at 13:46
  • 1
    `update` will only work on visible widgets ([doc](https://doc.qt.io/qt-5/qwidget.html#update)), and the `QPushButton` is not visible since the `w.show()` method is called before the button is created – PRMoureu Jul 20 '19 at 14:00
  • Didn't get it. What's the point of update( ) then if the widget must be created before? Can you give a minimal example? – Neeraj Kumar Jul 20 '19 at 14:26
  • An `update` or a `repaint` is used to trigger a refresh after some properties were changed, but it never touch hidden widgets. Check this [example](https://wiki.python.org/moin/PyQt/Adding%20custom%20signals%20to%20a%20simple%20painted%20widget) of `update` case. – PRMoureu Jul 20 '19 at 16:10