PySide2 UI перестает отвечать при вводе некоторое время l oop после его отображения - PullRequest
0 голосов
/ 29 апреля 2020

У меня возникают проблемы, когда мой QtWidget перестает отвечать, если я пытаюсь использовать некоторое время l oop после вызова метода widget.show() для объекта QtWidget. Сначала я думал, что проблема в том, как я использую сигналы и слоты. Я создал свой собственный сигнал с new_data = Signal(float), и я выполнял выборку данных с интервалом, установленным с помощью вызова time.sleep() в этом интервале, в то время как l oop, и испускал сигнал new_data каждый раз, когда отбирались данные. Это было связано с методом в моем QtWidget, который просто устанавливает текст метки в QtWidget для отображения новых данных.

Однако после некоторого тестирования я обнаружил, что если я ТОЛЬКО пытаюсь print("in loop") внутри этого, пока l oop, я получаю то же самое поведение. Объект QtWidget перестает отвечать. Как правильно обновить интерфейс PySide2 с интервалом c снаружи объекта интерфейса? Могу ли я, возможно, запустить интерфейс как процесс и добавить в него обновленные данные с помощью очереди? Я представляю, что это возможно, но мне трудно найти пример. Интерфейс - это только одна часть этого приложения, созданная в основном в Python, и у меня будет несколько процессов и несколько очередей, помимо интерфейса Qt. Вот код:

import sys
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication, QWidget
from PySide2.QtCore import QFile, QObject, Signal, Slot
import time
import NI9213 

class MyDaq(QObject):
    new_daq_data = Signal(float)

    def __init__(self):
        QObject.__init__(self)

        daq_channels = "cDAQ1Mod2/ai0"
        self.daq = NI9213.NI9213(channels=daq_channels)

    def sample_daq(self):
        data = self.daq.read_all()
        self.new_daq_data.emit(data)

class DigitalDisplay(QWidget):

    def __init__(self):
        #Initialize the QWidget object used to create the user interface
        QWidget.__init__(self)

        #Load the user interface
        designer_file = QFile("signal_digital_display.ui")
        designer_file.open(QFile.ReadOnly)
        loader = QUiLoader()
        self.ui = loader.load(designer_file, self)
        designer_file.close()

        #Add title to the UI window
        self.setWindowTitle("Digital Display")

        self.mode = 'run'

        self.ui.stopButton.clicked.connect(self.stopMode)

        self.sampling_period = 0.1

    @Slot(float)     
    def refresh_data(self, data):
        self.ui.label.setText(str(data))

    def stopMode(self):
        self.mode = 'stop'

if __name__ == "__main__":
    app = QApplication(sys.argv)
    digital_display = DigitalDisplay()
    digital_display.show()

##    data = MyDaq()
##    data.new_daq_data.connect(digital_display.refresh_data)
##
    while(digital_display.mode=='run'):
        print("after display.show")

##        data.sample_daq()
        time.sleep(digital_display.sampling_period)

    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 01 мая 2020

Проблема здесь в том, что перед началом события Qt у вас есть бесконечное l oop l oop.

if __name__ == "__main__":
    app = QApplication(sys.argv)  # [1]
    digital_display = DigitalDisplay() 
    digital_display.show()  # [2]

    while(digital_display.mode=='run'):
        print("after display.show")
        time.sleep(digital_display.sampling_period)  # [3]

    sys.exit(app.exec_()) # [4]

[1] Это создает объект QApplication. Он еще не запускает событие l oop.

[2] Создайте свой виджет и откройте новое окно для его отображения. Операционная система будет создавать события для окна, но они не будут влиять на само приложение, пока мы не запустим событие l oop.

[3] digital_display.mode никогда не изменится. Это бесконечное l oop, и Python никогда не продвинется выше этой точки.

[4] Здесь мы запускаем событие приложения l oop и закрываем процесс, как только Приложение завершено. Но мы никогда не доберемся сюда.

Вместо этого вам нужно создать QTimer для виджета DigitalDisplay, который периодически запускает сигнал, который может быть подключен к data.sample_daq.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...