0

If I open a window from the main() method it is displayed correctly.

enter image description here

If I open the same window out of a class instantiated from the main() method (WorkerClass), the window is only partially displayed, all the content inside (e.g. a QText) edit is missing.

enter image description here

Here's the code I used to reproduce this with a minimal amount of code:

import sys, time

from PyQt5.QtWidgets import QApplication, QTextEdit
from PyQt5.QtCore import QObject
        
class StatusWindow(QTextEdit):
    def __init__(self):
        super().__init__()

    def appendText(self, text):
        self.append(text)
 
class WorkerClass(QObject):
    def __init__(self):
        super().__init__()
        
    def openWindow(self):
        s = StatusWindow()
        s.show()
        s.appendText('opened from WorkerClass')
        
        time.sleep(10)

def main():
    app = QApplication(sys.argv)

    win = StatusWindow()
    win.show()
    win.appendText('opened from main()')
    
    work = WorkerClass()
    work.openWindow()
    
    sys.exit(app.exec_())
 
if __name__ == '__main__':
    main()

What goe's wrong here? How to fix this example to be able to get the window opened from WorkerClass displayed correctly?

Stefan
  • 113
  • 7
  • First of all, no blocking functions (including while loops) should ever happen in UI related code, so remove the `time.sleep`. Then, if you're planning on using that WorkerClass in a separate thread, and you're going to create that window from that thread, then don't: creation and access to UI elements is not allowed from external threads, and you must use Qt signals and slots instead. – musicamante Jun 11 '21 at 10:08
  • `time.sleep` is there to keep the window open for a limited amout of time. Without `time.sleep` the window closes immediately, which might be related to my problem. Worker is missleading here as there is no plan to place this in a thread. – Stefan Jun 11 '21 at 11:15
  • `time.sleep` is **exactly** the reason for which you can't see the contents of the window: it blocks the event queue, so the UI becomes unresponsive and is not correctly painted (with `sleep` you're blocking *all* events, including important ones such as `paintEvent`, which is responsible of drawing the widgets). Make the window an instance member (change `s = StatusWindow()` to `self.s = StatusWindow()`) and use a singleShot if you want to close it after a certain amount of time (`QtCore.QTimer.singleShot(10000, self.s.close)`). – musicamante Jun 11 '21 at 11:59

1 Answers1

0

Many thanks to musicamante, know I understand what happens.

The StatusWindow would also build correctly if instantiated from WorkerClass. If time.sleep is replaced by the Qtimer you can proove this.

In my example the window is not build correctly as the whole application is too busy, here simulated with time.sleep, and will never find the time to properly finish the window as long WorkerClass is running.

Stefan
  • 113
  • 7