Пример #1
0
    def __init__(self, cancel_callback=None, have_qapp=False, **kwargs):
        self.kwargs = kwargs

        # Check if a QApplication instance already exists.
        # If a QApplication is already initialized, this means that we
        # will have to do some interesting workarounds regarding queues
        # and multiprocessing.
        #
        # This is due to the fact that with multiprocessing, on *nix
        # platforms, this is achieved with os.fork(). Forking means
        # creating a new process with a copy of the program's memory...
        # which includes everything, not just Python internal memory!
        #
        # This includes PyQt's (and thus Qt's) C++ side, as well as any
        # other resources opened by PyQt/Qt. Copying Qt's memory data
        # doesn't make too much sense - if a window was open, fork()
        # would copy the window data... and that would result in two
        # windows.
        #
        # Except that you wouldn't have two windows, you'd just
        # have very odd behavior since the forked process is trying to
        # access the same window on the screen, leading to weird
        # behavior and errors!
        #
        # Hence, we need to copy only the data we need (almost nothing,
        # except for the queue), and work from there.
        #
        # On the topic of queues - fork() works nicely though with
        # multiprocessing queues, since essentially multiprocessing
        # just pipes the queue data to the process.
        #
        # If we are on Python >= 3.4, there's a new feature that lets
        # us configure how we want to launch our process - via spawning,
        # or simply just opening a new process (no fork)! Queues still
        # work (since it's just piping), so this lets us achieve
        # multiprocessing with PyQt successfully (and easily)!
        #
        # If we are NOT on Python >= 3.4... then we need to play around
        # a bit. Thankfully, multiprocessing already provides a lot of
        # good infrastructure - we just have to write the way to
        # create a new process!
        #

        # Assume that we're in the easy life!
        # 1 = multiprocessing, 2 = our implementation
        self.process_type = 1

        # First, check if we even need to care about this.
        if have_qapp or (QtCore.QCoreApplication.instance() != None):
            # OK, so we need to make sure we don't fork().
            print("ANTI-FORK required to run. Attempting to do that!")

            # If we are using Python >= 3.4, we can use this new little
            # trick (spawn method!) to make multiprocessing work with
            # PyQt.
            if (sys.version_info >= (3, 4)):
                multiprocessing.set_start_method('spawn')
            else:
                # We need to do our own tricks!
                self.process_type = 2

        if self.process_type == 1:
            # multiprocessing, as usual
            self.process_queue = multiprocessing.Queue()
            self.process = ProgressProcessMP(self.process_queue, **kwargs)
        else:
            # Do alternative method
            raise Exception("Anti-fork for python <3.4 not implemented yet!")
            pass

        self.cancel_callback = cancel_callback

        self.closed_cleanly = None

        self.proc_started = False