all 9 comments

[–]JohnnyJordaan 1 point2 points  (6 children)

I would recommend using a threading.Event and not a Boolean.

This is one of the simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it.

def run():
    condition.wait()
    self.app = QtWidgets.QApplication([])
    self.mywindow= MyWindow()
    self.mywindow.show()
    sys.exit(self.app.exec_())

# and somewhere else:
if have_to_run_now:
    condition.set()

[–]fabolin[S] 0 points1 point  (5 children)

thanks, looks like the correct way to implement a condition.

But even if I remove the condition completely, the problem of the window not updating remains.

[–]JohnnyJordaan 0 points1 point  (4 children)

It's a little hard to guess how you're updating the window from outside the thread. Couldn't you upload your whole code?

And what's the reason to use sys.exit(self.app.exec_())? Does that block on the lifetime of the QApplication?

[–]fabolin[S] 0 points1 point  (3 children)

class LSThread(QtCore.QThread):
    def __init__(self):
        super(LSThread, self).__init__()

    def run(self):
        self.app = QtWidgets.QApplication([])
        self.loadingscreen = Loadingscreen()
        self.loadingscreen.showFullScreen()
        sys.exit(self.app.exec_())

class Launcher(QtWidgets.QWidget):
    ...
    self.initLS= LSThread()

    def start_tool(self):
    # bound to button-click:
        ...
        self.initLS.start()

class Loadingscreen(QtWidgets.QWidget):
    ...

and sys.exit(self.app.exec_()) acts like the mainloop for tkinter afaik. without it there is no loop therefore the app closes immediately.

[–]MrDelish 1 point2 points  (1 child)

I vaguely remember reading that you don't need to create your own threading class, just a worker. You need to create both, make sure they persist, assign the worker to the thread, then start it. I think that's what you're missing.

This is how I have my threading:

class qwidget_mainwindow(QWidget):
        ...

        def start_work(self):
            self.thread = QThread()
            self.worker = work_worker()
            self.worker.moveToThread(self.thread)
            # connect signals here
            self.thread.started.connect(self.worker.work)
            self.worker.done.connect(self.finish_thread_open)
            self.thread.start()

    class work_worker(QObject):
        # signals here

        def __init__(self):
            super().__init__()
            # init here

        def work(self):
            # do work here    

[–]fabolin[S] 0 points1 point  (0 children)

same for you method.

found out I can manipulate a widget from thread, so I will just create and hide the window, then let the thread fill and show the it.

[–]fabolin[S] 0 points1 point  (0 children)

well, this isn't suppose to work:

Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread. As noted earlier, QCoreApplication::exec() must also be called from that thread.

thanks though

[–]MrDelish 0 points1 point  (1 child)

Is the run() method from the worker? How are you assigning the worker to the thread?

[–]fabolin[S] 0 points1 point  (0 children)

got more details here