periodi c опрос порта или аппаратной точки ввода-вывода на Raspberry Pi - PullRequest
1 голос
/ 13 июля 2020

При разработке приложения с использованием Qt5 и Python вы обычно управляете событиями. Без пота, работает как шарм. Однако бывают случаи, когда вам нужно опросить состояние некоторого аппаратного GPIO (например, кнопки pu sh), или получить некоторую информацию из последовательного порта, или чего-то вроде демона gpsd.

Что такое предпочтительный способ справиться с этим? Скажем, через QTimer каждые 50 мс c? Или есть какой-то другой метод, который я не нашел? Лучше настроить триггер на GPIO pi (https://www.ics.com/blog/control-raspberry-pi-gpio-pins-python) или есть ли конфликт с Qt5 Gui?

Basi c документация не смотрит ужасно, и я, конечно, могу следовать некоторым примерам, но не знал, есть ли лучший / канонический / дополнительный метод Pythoni c.

https://doc.qt.io/qtforpython/PySide2/QtCore/QTimer.html

https://python-catalin.blogspot.com/2019/08/python-qt5-qtimer-class.html

1 Ответ

2 голосов
/ 14 июля 2020

Я не думаю, что существует решение pythoni c , не потому, что вы не можете использовать python, а потому, что python не имеет отношения к topi c. И нет канонического решения , все будет зависеть от приложения.

Исходя из моего опыта, я обнаружил, что намного проще повторно использовать библиотеки, которые обрабатывают GP IOs, такие как Rpi.GPIO или гпиозеро. Эти библиотеки имеют стратегию создания потоков, в которых отслеживается состояние контактов, поэтому вы не можете использовать обратные вызовы напрямую для обновления GUI, но вы должны реализовать оболочку (см. this , например).

тривиальный пример:

import sys

from gpiozero import Button

from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
from PyQt5.QtWidgets import QMainWindow, QApplication


class ButtonManager(QObject):
    pressed = pyqtSignal()

    def __init__(self, parent=None):
        super(ButtonManager, self).__init__(parent)
        self._button = Button(20)
        self._button.when_pressed = self._on_when_pressed

    def _on_when_pressed(self):
        self.pressed.emit()


class MainWindow(QMainWindow):
    @pyqtSlot()
    def on_pressed(self):
        print("pressed")


def main():

    app = QApplication(sys.argv)
    w = MainWindow()

    button_manager = ButtonManager()
    button_manager.pressed.connect(w.on_pressed)

    w.show()

    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

Если вы собираетесь использовать последовательные порты, то лучшим вариантом является использование последовательного порта Qt, поскольку, в отличие от pyserial, нет необходимости использовать потоки, но уведомление отправляется сигналов (см. this , например)

Другой вариант - использование QTimer.

...