8

I'm trying to figure out if subclassing QtConcurrent and writing a run method inside it will work:

class Task(QtCore.QtConcurrent):

     def run(self, function):
           function()

Or is it completely useless?

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Elteroooo
  • 2,913
  • 3
  • 33
  • 40

3 Answers3

18

It's completely useless, because QtConcurrent is a namespace, not a class.

Also, neither PyQt nor PySide provide any of the functionality provided by QtConcurrent, because it's all template-based and therefore impossible to wrap.

PS: the PySide documentation you linked to is for the ReduceOption enum. Since it's doubtful whether that enum has any use outside the QtConcurrent namespace, it's probably a bug that PySide includes it.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • 1
    Very interesting. I was just about to experiment a little bit with `QtConcurrent` in PyQt5 when I realized that I can't find anything. Thanks for the hint. I guess C++ it is. :D – rbaleksandar Sep 05 '16 at 15:08
  • Might it be possible for someone to rewrite all this QtConcurrent in Python? I assume it wouldn't be very easy, but might it be possible? It seems frustrating that we have Futures in Python's concurrent.futures but PyQt5 is stuck in the Dark Ages. – mike rodent Jan 04 '22 at 14:26
  • @mikerodent [Templates](https://en.wikipedia.org/wiki/Template_(C%2B%2B)) are a C++ feature, which means `QtConcurrent` cannot be implemented in any meaningful sense in Python. You might be able to come up with some alternative API that reproduced *some* of the functionality, but it wouldn't really be `QtConcurrent` any more (e.g. [qconcurrent.py](https://gist.github.com/ales-erjavec/5ef43c5b3907a9e4924eec09bfb9d9c6)). I doubt whether it would ever be worth anyone's time trying to reproduce *all of it*, though (certainly the author of PyQt has never shown any interest in doing so when asked). – ekhumoro Jan 04 '22 at 18:25
0

The class you are looking for is QRunnable.

Grumbel
  • 6,585
  • 6
  • 39
  • 50
  • That does not provide the ability to call any function I don't think... Only option here is to inherit from QThread. See my solution above. – MathCrackExchange Mar 04 '19 at 22:25
0

I am stuck on the same problem in PyQt5. I guess the only solution is to do this locally:

def connect(self):
    class ConnectThread(QThread):
        def __init__(self, func):
            super().__init__()
            self.func = func
        def run(self):
            self.func()
    self.connectThread = ConnectThread(self._connect)
    self.connectThread.start()

def _connect(self):
    if self._driver is None:
        uri = self.uriString()
        if uri and self.user and self.password:
            self.statusMessage.emit("Connecting to the Graph Database....", -1, "color:blue;")
            try:
                self._driver = GraphDatabase.driver(uri, auth=(self.user, self.password))
                self.statusMessage.emit("Connected!", 5000, "color:green;")
            except Exception as e:
                self.clearStatusMessage.emit()
                Error(str(e)).exec_()
                if __debug__:
                    raise e

And remember to set the thread to a member variable: self.thread = ... or else your thread reference will go out of scope, and most likely the thread object deleted.

You could also move your function-to-call into a local definition of it as Python allows both nested functions and classes within one another!

MathCrackExchange
  • 595
  • 1
  • 6
  • 25