Как обновить поле вне функции __init__() с помощью pyqt5

Я читаю датчик и хочу отобразить его вывод в виде десятичного числа в графическом интерфейсе, используя PyQt5. Я нашел несколько руководств, в которых упоминается функция label.setText('myStr'). Однако это не работает для моей настройки, потому что мне нужно обновить поле на основе ввода из другой функции. Я еще не очень хорошо знаком с PyQt5, и я был бы признателен за любое понимание того, как следует подходить к этой проблеме. Примечание. (Я использую LCM для получения данных от Raspberry Pi. Я не уверен, что это имеет отношение к проблеме, но это помогает объяснить мой код ниже.)

Вот что я пытаюсь сделать:

class Home_Win(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)
        loadUi("sensor_interface.ui", self)
        self.label_temp.setText('temperature') #Just to verify that I can change it from here

    def acquire_sensors(self):
        temp = 0  #Make variable available outside nested function
        def listen(channel, data):
            msg=sensor_data.decode(data)
            temp = msg.temperature

        lc = lcm.LCM()
        subscription = lc.subscribe("sensor_data_0", listen)

            while True:
                lc.handle()
                self.label_temp.setText(str(temp))

Любые мысли о том, как я могу обновить графический интерфейс для отображения показаний, которые я получаю от своих датчиков? Спасибо!


person Charles R    schedule 25.06.2020    source источник


Ответы (2)


Ты почти там. Все, что вам нужно сделать, это сохранить пользовательский интерфейс в переменной экземпляра в __init__:

self.ui = loadUi("sensor_interface.ui", self) 

Затем, предполагая, что label_temp — это имя вашего виджета QLabel, просто выполните:

self.ui.label_temp.setText(str(temp))
person mkam    schedule 26.06.2020
comment
Спасибо за чаевые! В итоге я включил это в свой код, хотя мне также пришлось переключиться на QLineEdit вместо QLabel и repaint(), прежде чем я смог заставить графический интерфейс выводить оперативные обновления при чтении потока данных. - person Charles R; 01.07.2020
comment
Рад, что помог. Однако вам не нужно вызывать метод repaint() — в обычных условиях это происходит автоматически в ответ на изменение текста виджета. Это заставляет меня думать, что в вашем коде должно быть что-то, что блокирует обработку событий рисования. - person mkam; 01.07.2020
comment
Это связано с моим бесконечным циклом while? Моя цель, чтобы пользователь щелкнул кнопку, чтобы начать сбор данных и продолжить чтение данных (возможно, в течение нескольких часов или дней). В течение этого времени он должен отображать текущую температуру для пользователя. (Это сделано для удобства пользователя. Данные также будут записаны в файл .csv для последующего анализа.) Похоже, что графический интерфейс не хочет автоматически обновлять виджет, пока он не выйдет из цикла обработки событий. Использование функции repaint() вызывает обновление перед завершением цикла событий, или, по крайней мере, я думаю, что это то, что происходит? - person Charles R; 01.07.2020
comment
Да, ваш бесконечный цикл опроса должен блокировать цикл событий Qt. Конечно, вы всегда можете вызывать QApplication.processEvents каждый раз через свой цикл, но это неэлегантно. Реальный корень проблемы заключается в том, что приложение в том виде, в каком оно написано, плохо структурировано — вы должны запустить Qt в основном потоке и создать отдельный поток (используя QThread) для цикла фонового опроса. Цикл опроса может выдавать простой сигнал каждый раз, когда элемент данных считывается с датчика, что запускает функцию в основном потоке для обновления текста вашего виджета. Таким образом, пользовательский интерфейс остается отзывчивым. - person mkam; 02.07.2020

Оказалось, что мне нужно было добавить repaint(). Я также переключился на QLineEdit, так как мне показалось, что это работает лучше. Итак, внутри цикла while у меня теперь есть:

self.ui.lineEdit_temp.setText(str(temp))
self.ui.lineEdit_temp.repaint()

Теперь это выводит оперативные обновления графического интерфейса при чтении потока данных.

person Charles R    schedule 30.06.2020