Гарантии в сигналах PyQt и сравнение использования очереди - PullRequest
1 голос
/ 01 мая 2019

Я рассматриваю два механизма для доставки результатов между различными потоками приложения. По возможности создается очередь Python или PyQt, которая заполняется одним потоком и используется потоком. Но я мог бы также использовать PyQt Signal / Slots для той же цели. Преимущество последнего состоит в том, что у меня может быть больше одного потребителя без какой-либо дополнительной работы, но мне было интересно, есть ли недостаток. В частности,

  1. гарантируется ли передача сигналов в подключенный слот или их можно пропустить?
  2. гарантированно ли принимаются сигналы в том же порядке, в котором они излучались?

1 Ответ

1 голос
/ 01 мая 2019

1.гарантированно ли сигналы передаются в подключенный слот или они могут быть пропущены?

Qt гарантирует, что слот получает информацию.В фоновом режиме в Qt сигналы находятся в очереди, которая обрабатывается циклом событий, и это является преимуществом, поскольку очередь имеет доступ к соединениям.

2.гарантированно принимаются сигналы в том же порядке, в котором они были отправлены?

Поскольку сигналы в моем предыдущем ответе Qt сохраняют информацию, которая будет передаваться в очереди.Вы также должны знать, что слоты вызываются только тогда, когда синхронная задача заканчивается или в каком-то вторичном потоке есть спящий режим.Затем, чтобы проверить, что порядок соблюден, мы можем использовать следующий пример, где испускаются 5 излучений сигнала, и слот вызывается в спящем режиме.

from PyQt5 import QtCore


class FooObject(QtCore.QObject):
    foosignal = QtCore.pyqtSignal(int)

    @QtCore.pyqtSlot()
    def run(self):
        counter = 0
        for _ in range(10):
            for i in range(5):
                self.foosignal.emit(counter)
                counter += 1
            QtCore.QThread.sleep(1)


if __name__ == "__main__":
    import sys

    app = QtCore.QCoreApplication(sys.argv)
    foo = FooObject()
    thread = QtCore.QThread()
    thread.start()
    foo.moveToThread(thread)
    foo.foosignal.connect(print)
    QtCore.QTimer.singleShot(1000, foo.run)
    sys.exit(app.exec_())
...