如果在为QtWidget
对象调用widget.show()
方法后尝试使用while循环,则我的QtWidget
会停止响应。我最初认为问题在于我如何使用信号和插槽。我已经用new_data = Signal(float)
创建了我自己的信号,并且我在while循环中以time.sleep()
调用建立的间隔对数据进行采样,并在每次对数据采样时发出new_data信号。这与我的QtWidget
中的一个方法有关,该方法只设置QtWidget
中标签的文本以显示新数据。
然而,经过一些测试,我发现如果我只在while循环中尝试print("in loop")
,我会得到同样的行为。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_())
这里的问题是在启动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] 创建你的小部件并打开一个新窗口来显示它。操作系统会为窗口创建事件,但在我们启动事件循环之前,它们对应用程序本身没有影响。
[3]digital_display.mode
永远不会改变。这是一个无限循环,Python永远不会超过这一点。
[4]在这里我们启动应用程序事件循环,并在应用程序完成后关闭流程。但我们从来没有到过这里。
您应该做的是在DigitalDisplay
小部件上创建一个QTimer
,该小部件定期触发一个可以连接到data.sample_daq
的信号。