Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 获取从串行到输出到TexCtrl的持续更新_Python_Python 2.7_Wxpython_Wxwidgets - Fatal编程技术网

Python 获取从串行到输出到TexCtrl的持续更新

Python 获取从串行到输出到TexCtrl的持续更新,python,python-2.7,wxpython,wxwidgets,Python,Python 2.7,Wxpython,Wxwidgets,我有一个我用wxPython编写的gui,它作为一个软件控制器工作,变成一个PID类型的热控制器。 我需要从热控制器获得恒定的读数,以一致地输出设备的当前温度 假设我在另一个文件中有此函数: def temp_read(): #this function will query a controller, then read the value 我导入该函数,并将其设置为TextCtrl小部件的值: out_current = wx.TextCtrl(self,

我有一个我用wxPython编写的gui,它作为一个软件控制器工作,变成一个PID类型的热控制器。 我需要从热控制器获得恒定的读数,以一致地输出设备的当前温度

假设我在另一个文件中有此函数:

    def temp_read():
        #this function will query a controller, then read the value
我导入该函数,并将其设置为TextCtrl小部件的值:

    out_current = wx.TextCtrl(self, pos=(250,8), size=(110,23), style=TE_READONLY)
    out_temp = temp_read()#get value from function
    out_current.SetValue(out_temp)#set value to widget

我如何设置它,使其不断输出,同时让gui保持功能,以允许用户设置其余的控制参数(设置温度和其他项目)

您没有指定如何获取串行数据。不过,我想您将使用
pyserial
。读取序列的主要问题是,在下一个字符到达之前,读取序列会阻塞。而且,由于它将立即尝试读取下一个字节(并再次阻塞),GUI将永远不会空闲

因此,本质上,您必须在单独的线程中分离串行读取,并将结果安全地传递回线程

为了读出Arduino,我创建了一个(这也更详细地解释了为什么需要线程)。删除DRS/DTR的线路时,它将适用于任何串行设备


编辑:如果您进一步查看pyserial库并查看
wxPython
示例,它正在使用线程。

关于我的评论:
这来自pyserial手册:

>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)   
>>> x = ser.read()          # read one byte   
>>> s = ser.read(10)        # read up to ten bytes (timeout)   
>>> line = ser.readline()   # read a '\n' terminated line   
>>> ser.close()   


>>> ser = serial.Serial(1, 38400, timeout=0,   
...                     parity=serial.PARITY_EVEN, rtscts=1)   
>>> s = ser.read(100)       # read up to one hundred bytes   
...                         # or as much is in the buffer   
如果您发现您必须走线程路线,请参阅Fredrik Haard在此处编写的公认答案

他的例子如下:

import threading

connected = False
port = 'COM4'
baud = 9600

serial_port = serial.Serial(port, baud, timeout=0)

def handle_data(data):
    print(data)

def read_from_port(ser):
    while not connected:
        #serin = ser.read()
        connected = True

        while True:
           print("test")
           reading = ser.readline().decode()
           handle_data(reading)

thread = threading.Thread(target=read_from_port, args=(serial_port,))
thread.start()

使用wx的计时器类定期调用更新小部件的函数。轮询将不起作用(将被阻止),至少对于
pyserial
。如果您可以从串行设备读取给定数量的字节,那么wx.Timer()是一种方法。我敢打赌,热控制器可以提供包含当前温度的固定字节数。因此,如果您可以将读取限制为固定的字节数,它就不会阻塞,因此我使用的控制器有一个时髦的小协议。我向它发送一个字符串*01000021\r它查询控制器返回当前温度(*表示消息开始,010000是返回当前温度的实际命令,21是校验和,\r结束命令)。它返回以下内容:*00fa27\r其中00fa是当前temp的十六进制值(两个值的互补),27是校验和。虽然这无疑是一个“时髦的协议”,但关于这个问题,我不清楚评论的原因。除非您确认您确实收到了固定长度的邮件。