我有一个问题,我的 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_())
这里的问题是,你在启动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
.