0

This question applies to Raspberry Pi 3B+ running Stretch. Python 3.5. The user interface for a Qt5 application is created. If there is some time-consuming setup before app.exec_(), only an empty window frame is visible, instead of the fully rendered window.

This behavior is different from what's seen on MacOs, for example, where the window is, indeed, rendered.

import time
import sys

from PyQt5.QtWidgets import QApplication, QMainWindow

# the main GUI window
class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Test')

# create and run the interactive application
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = App()              # create the application window
    mainWindow.show()               # this should show the window
    app.processEvents()             # everything should be updated

    # delay.  only an empty window frame is shown.
    print ('Delay 10s...')
    time.sleep(10)

    # enter the GUI loop.  now the window is rendered.
    sys.exit(app.exec_())

Only an empty window frame is shown. What's expected is a fully rendered window (in this case, it should be just a white empty window but if there are other GUI elements, they should show as well.

mwgrabau
  • 21
  • 3
  • This is not possible: nothing happens, graphically, before the event loop starts spinning. On Mac, it’s a mirage: no controls will appear. – Kuba hasn't forgotten Monica Jan 23 '19 at 16:56
  • Actually, on MacOs, app.processEvents() will render the entire GUI for the main window (which I didn't include in the code snippet, above, for clarity). – mwgrabau Jan 23 '19 at 21:47
  • It's not portable and there are no tests in Qt to guarantee that it will work, AFAIK. You're depending on undefined behavior. There's no reason for you to do it that way: it's likely an XY problem, and you should tell us what do you need to do so urgently in the main thread that it can't be done in chunks using a zero-duration timer (the primitive for "doing stuff along other things"), or another thread. – Kuba hasn't forgotten Monica Jan 24 '19 at 20:20
  • There is a bunch of initialization of a cellular modem including waiting for the modem to complete connecting to the cellular network and getting a GPS fix, that takes about 30 seconds. During those 30 seconds I want to have at least a message window on the screen. I'd be very interested how I could do that in another thread. – mwgrabau Jan 24 '19 at 21:25
  • Put all the initialization into a separate function, run it via `QtConcurrent::run`. Done. But that's still synchronous programming - you'll want an async state machine to do it in a way that won't prevent your application from cleanly exiting, or getting good progress reports, or restarting/canceling the actions should they stall. See e.g. [this answer](https://stackoverflow.com/questions/32486198/sending-a-sequence-of-commands-and-wait-for-response/32595398#32595398) for inspiration on how to do it. – Kuba hasn't forgotten Monica Jan 25 '19 at 12:50

0 Answers0