PySide2 UI在显示后进入while循环时停止响应。

问题描述 投票:0回答:1

我有一个问题,我的 QtWidget 如果我在调用了 widget.show() 的方法 QtWidget 对象。我最初认为问题出在我如何使用信号和插槽上。我用 new_data = Signal(float) 而我是在一个既定的时间间隔内对数据进行采样。time.sleep() 的调用,并在每次数据被采样时发出new_data信号。这连接到我的 QtWidget 中设置了一个标签的文本。QtWidget 来显示新的数据。

然而,经过一些测试,我发现如果我只尝试使用 print("in loop") 在那个 while 循环里面,我得到了同样的行为。QtWidget对象停止响应。从接口对象外部定期更新PySide2接口的正确方法是什么?我是否可以将接口作为一个进程运行,然后用队列给它更新数据?我成像这是可能的,但很难找到一个例子。接口只是这个主要用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_())
python multiprocessing queue pyside2 qt-signals
1个回答
0
投票

这里的问题是,你在启动Qt事件循环之前有一个无限循环。

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对象。它还没有启动事件循环。

2] 创建你的widget并打开一个新的窗口来显示它。操作系统将为窗口创建事件,但在我们启动事件循环之前,它们对应用程序本身没有影响。

[3] digital_display.mode 将永远不会改变。这是一个无限循环,Python 将永远不会超过这个点。

[4] 我们启动应用程序事件循环,并在应用程序完成后关闭该进程。但我们永远不会到达这里。

你应该做的是创建一个 QTimer 在...上 DigitalDisplay 小部件,定期发出信号,可以连接到一个小部件。data.sample_daq.

© www.soinside.com 2019 - 2024. All rights reserved.