Beispiel #1
0
 def __init__(self, qbaseobject, callback, signals=None, connections=None, mutex_expiry=5000):
     """
     Args:
         qbaseobject (QBaseObject):
             The QBaseObject instance this is attached to. Whenever the task
             is started, it will be checked for a parent window/progressbar.
     """
     self._qbaseobject = qbaseobject
     SoloThreadedTask.__init__(self,
         callback     = callback,
         signals      = signals,
         connections  = connections,
         mutex_expiry = mutex_expiry,
     )
Beispiel #2
0
 def __init__(self,
              progressbar,
              callback,
              signals=None,
              connections=None,
              mutex_expiry=5000):
     self._progressbar = progressbar
     SoloThreadedTask.__init__(
         self,
         callback=callback,
         signals=signals,
         connections=connections,
         mutex_expiry=mutex_expiry,
     )
Beispiel #3
0
    def __init__(self):
        QtWidgets.QListWidget.__init__(self)

        self._sem_rendering = QtCore.QSemaphore(1)

        self._thread_loading = SoloThreadedTask(
            callback=self._find_list_items,
            signals={
                'add_item': str,
                'clear': None,
            },
            connections={
                'add_item': [self.addItem],
                'clear': [self.clear],
            },
        )
Beispiel #4
0
    def start(self, expiryTimeout=-1, threadpool=None, wait=False, *args, **kwds ):
        """
        Looks for/connects the progressbar.
        """

        with threading.Lock():
            jobid = uuid.uuid4().hex

            # check if this QBaseObject has a parent window,
            # and if that window has a method called `progressbar`
            # (presumably yielding a progressbar)
            progressbar = None
            if hasattr( self._qbaseobject, 'window' ):
                if hasattr( self._qbaseobject.window(), 'progressbar' ):
                    progressbar = self._qbaseobject.window().progressbar()


            # default arguments
            connections = self._connections.copy()
            if not connections:
                connections = {}

            if progressbar:
                progbar_connections = {
                    'incr_progress' : functools.partial( progressbar.incr_progress, jobid=jobid ),
                    'add_progress'  : functools.partial( progressbar.add_progress,  jobid=jobid ),
                    'returned'      : functools.partial( progressbar._handle_return_or_abort, jobid=jobid ),
                    'exception'     : functools.partial( progressbar._handle_return_or_abort, jobid=jobid ),
                }
            else:
                progbar_connections = {}


            for signal in progbar_connections:
                if signal in connections:
                    connections[ signal ].append( progbar_connections[signal] )
                else:
                    connections[ signal ] = [ progbar_connections[signal] ]


            SoloThreadedTask.start(self,
                               expiryTimeout = expiryTimeout,
                               threadpool    = threadpool,
                               wait          = wait,
                               _connections  = connections,
                               *args,**kwds
                           )
Beispiel #5
0
    def start(self,
              expiryTimeout=-1,
              threadpool=None,
              wait=False,
              *args,
              **kwds):
        """
        Wraps :py:meth:`qconcurrency.threading_.SoloThreadedTask.start` ,
        adding signal-connections so that they update a progressbar.

        See Also:

            * :py:meth:`qconcurrency.threading_.SoloThreadedTask.start`
        """

        jobid = uuid.uuid4().hex

        connections = self._connections.copy()
        if not connections:
            connections = {}

        progbar_connections = {
            'incr_progress':
            functools.partial(self._progressbar.incr_progress, jobid=jobid),
            'add_progress':
            functools.partial(self._progressbar.add_progress, jobid=jobid),
            'returned':
            functools.partial(self._progressbar._handle_return_or_abort,
                              jobid=jobid),
            'exception':
            functools.partial(self._progressbar._handle_return_or_abort,
                              jobid=jobid),
        }

        for signal in progbar_connections:
            if signal in connections:
                connections[signal].append(progbar_connections[signal])
            else:
                connections[signal] = [progbar_connections[signal]]

        SoloThreadedTask.start(self,
                               expiryTimeout=expiryTimeout,
                               threadpool=threadpool,
                               wait=wait,
                               _connections=connections,
                               *args,
                               **kwds)
Beispiel #6
0
class MyThreadedList(QtWidgets.QListWidget):
    def __init__(self):
        QtWidgets.QListWidget.__init__(self)

        self._sem_rendering = QtCore.QSemaphore(1)

        self._thread_loading = SoloThreadedTask(
            callback=self._find_list_items,
            signals={
                'add_item': str,
                'clear': None,
            },
            connections={
                'add_item': [self.addItem],
                'clear': [self.clear],
            },
        )

    def load(self):
        """
        Loads list with items from a separate thread.
        If load is already in progress, it will be cancelled
        before the new load request starts.
        """
        self._thread_loading.start()

    def _find_list_items(self, signalmgr=None):
        """
        Adds 100 items to the list-widget,
        """
        signalmgr.clear.emit()

        for i in range(100):
            signalmgr.handle_if_abort(
            )  # check for a request-abort, and exit early

            # slow signals down, emitting one object at a time
            # so that job can be cancelled.
            # ( signals have no priority, once emitted,  )
            # ( you must wait for them all to be handled )
            self._sem_rendering.tryAcquire(1, 5000)
            signalmgr.add_item.emit(str(i))  # add an item to the list

    def addItem(self, item):
        """
        Unecessarily waits .01 seconds (so you can see widget updating live),
        then adds the item to the list.
        """
        time.sleep(0.01)
        try:
            QtWidgets.QListWidget.addItem(self, item)
        except:
            self._mutex_rendering.unlock()
            six.reraise(*sys.exc_info())

        if not self._sem_rendering.available():
            self._sem_rendering.release(1)

        # in this example, the wait is performed
        # in the UI thread - it never has a chance to process
        # QApp events (causing item to be rendered) until it runs
        # out of signals to fire. It is unlikely you will
        # need the following line in your production code.
        #
        QtCore.QCoreApplication.instance().processEvents()
from qconcurrency import QApplication
from qconcurrency.threading_ import SoloThreadedTask
from Qt import QtWidgets, QtCore
import six
import supercli.logging
import time
supercli.logging.SetLog(lv=10)

with QApplication():
    wid = QtWidgets.QPushButton('close me')
    wid.show()

    queue_finished = six.moves.queue.Queue()
    threadpool = QtCore.QThreadPool()

    def _callback(queue_finished, signalmgr=None):
        for i in range(3):
            signalmgr.handle_if_abort()
            time.sleep(0.05)
        queue_finished.put(True)

    task = SoloThreadedTask(callback=_callback, )
    task.start(
        queue_finished=queue_finished,
        threadpool=threadpool,
        wait=True,
    )