#! /usr/bin/env python3

import sys, logging
from PySide2 import QtCore, QtWidgets

class BaseClass(QtCore.QObject):

    def __init__(self):
        super().__init__()

    # Having the "@QtCore.Slot" decorator here, makes that the DerivedClass's 'triggered' slot is
    # called from the main thread... Go figure...
    #@QtCore.Slot()
    def triggered(self):
        logging.debug("BaseClass: triggered()")


class DerivedClass(BaseClass):

    def __init__(self):
        super().__init__()

    @QtCore.Slot()
    def triggered(self):
        logging.debug("DerivedClass: triggered()")


class Application(QtWidgets.QApplication):

    mySignal = QtCore.Signal()

    def __init__(self, argv):

        super().__init__(argv)

        # Make and start QThread with its own event loop.

        self._thread = QtCore.QThread()
        self._thread.start()

        # Make and start an instance 'derivedObject', and move it to the thread
        # we cust created. This means that its slots should be executed from the
        # thread's event loop from now on (no longer from the main thread).

        self._derivedObject = DerivedClass()
        self._derivedObject.moveToThread(self._thread)

        # Connect our Signal to the derivedObject's Slot.
        self.mySignal.connect(self._derivedObject.triggered)

        # emit our signal.
        self.mySignal.emit()

    def done(self):
        self._thread.quit()
        self._thread.wait()


def main():

    LOGGING_FORMAT = "[%(asctime)-15s | %(threadName)-12s | %(levelname)-8s | %(name)-40s] %(message)s"

    # Do basic configuration for the logging.
    logging.basicConfig(level = logging.DEBUG, format = LOGGING_FORMAT)

    app = Application(sys.argv)

    mainWindow = QtWidgets.QMainWindow()

    mainWindow.show()

    exitcode = QtWidgets.QApplication.exec_()

    app.done() # clean up everything

    logging.shutdown()

    return exitcode


if __name__ == "__main__":
    exitcode = main()
    sys.exit(exitcode)
    main()
