【问题标题】:How can I stream program output to wxpython listctrl?如何将程序输出流式传输到 wxpython listctrl?
【发布时间】:2017-04-29 01:43:48
【问题描述】:

我正在为学校制作项目,这是一个带有树莓派的温度测量平台,我正在尝试将我的数据连续流式传输到 GUI。请帮忙。

我在将输出输出到 wxListCtrl 时遇到问题。 这是我的代码:

import spidev
import time
import math
from time import strftime
import string
import os

spi = spidev.SpiDev()
spi.open(0, 0)
filename = strftime("%d-%b-%Y %H_%M_%S")

def read_adc(adcnum):
# read SPI data from MCP3304 chip, 8 possible adc's (0 thru 7)
    if adcnum > 7 or adcnum < 0:
        return -1

# Frame format: 0000 1SCC | C000 000 | 000 000
    r = spi.xfer2([((adcnum & 6) >> 1)+12 , (adcnum & 1) << 7, 0])
    adcout = ((r[1] & 15) << 8) + r[2]
    return adcout

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError:
        if not os.path.isdir(path):
            raise

def get_temperature(adc):
# read thermistor voltage drop and convert it to degrees of Celsius
    value = read_adc(adc)               #read the adc
    volts = (value * 3.3) / 4095        #calculate the voltage

    # check if the thermistor is connected to this channel
    if volts > 3.2:
        return 0

    ohms = (volts*10000)/(3.3-volts)    #calculate thermistor resistance
    lnohm = math.log1p(ohms)            #take ln(ohms)

    # a, b, & c values from www.rusefi.com/Steinhart-Hart.html
    # 0-50 C
    a =  0.001125256672
    b =  0.0002347204473
    c =  0.00000008563052732

    # Steinhart Hart Equation
    # T = 1/(a + b[ln(ohm)] + c[ln(ohm)]^3)
    t1 = (b*lnohm)                      #b[ln(ohm)]
    c2 = lnohm                          #c[ln(ohm)]
    t2 = c*math.pow(c2,3)               #c[ln(ohm)]^3
    temp = 1/(a + t1 + t2)              #calcualte temperature in K
    tempc = temp - 273.15               #K to C

    #print out info
    #print ("%4d/4095 => %5.4f V => %6.1f ? => %5.2f °K => %3.1f °C from adc     %d" % (value, volts, ohms, temp, tempc, adc))
    print ("%3.1f °C from sensor %d" % (tempc, adc))

    return tempc

make_sure_path_exists("./data")
'''while True:
    #write to log
    log = open("./data/"+filename+'.csv', 'a') #open a text file for logging
    log.write(strftime("%d/%m/%y,%H:%M:%S"))
    for x in range (0,8):
        log.write(",%3.1f" % (get_temperature(x)))
    log.write(strftime("\n"))
    log.close()
    time.sleep(5)'''

class Myframe(wx.Frame):

    def Close(self, event):
        dialog=wx.MessageDialog(self, 'For sure?', 'End work',  style=wx.OK | wx.CANCEL)
        x=dialog.ShowModal()
        dialog.Destroy()
        if x == wx.ID_OK:
            self.Close()


    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Temperature Monitoring", size=(1024,760))
        panel = wx.Panel(self, wx.ID_ANY)
        self.index = 0


        MenuListwa=wx.MenuBar()
        ProgMenu=wx.Menu()
        ProgMenuItem1=ProgMenu.Append(wx.ID_ANY,'Temperature','Read data')
        self.Bind(wx.EVT_MENU, self.OpenData, ProgMenuItem1)
        MenuListwa.Append(ProgMenu,'Data')

        ProgMenu=wx.Menu()
        ProgMenuItem1=ProgMenu.Append(wx.ID_EXIT, 'End', 'End program')
        MenuListwa.Append(ProgMenu, 'Exit')
        self.Bind(wx.EVT_MENU, self.Close, ProgMenuItem1)
        self.SetMenuBar(MenuListwa)


        self.list_ctrl = wx.ListCtrl(panel, size=(-1,600),
                         style=wx.LC_REPORT
                         |wx.BORDER_SUNKEN
                         )
        self.list_ctrl.InsertColumn(0, 'Record', width=100)
        self.list_ctrl.InsertColumn(1, 'Temperature', width=800)

        btn = wx.Button(panel, label='Add record')
        btn.Bind(wx.EVT_BUTTON, self.onStartTimer)

        self.timer = wx.Timer(self, wx.ID_ANY)
        self.Bind(wx.EVT_TIMER, self.add_records, self.timer)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
        panel.SetSizer(sizer)

def onStartTimer(self, event):
        print 'rekordy'
        self.timer.Start(10)

def add_records(self, event):
    while True:
        Temp=[]
        for ch in range(0,8):
            Temp.append(get_temperature(ch))
        line = "Record %s" % self.index
        self.list_ctrl.InsertStringItem(self.index, line)
        add1 = self.list_ctrl.SetStringItem(self.index, 1, Temp[self.index])
        for i in Temp:
            add1 += self.list_ctrl.SetStringItem(self.index, 1, Temp[self.index])
        self.index += 1
        time.sleep(30)


# Run
if __name__ == "__main__":
    app = wx.App(False)         
    frame = Myframe()
    frame.Show()
    frame.Update()
    app.MainLoop()

sn-p:

def onStartTimer(self, event):
    print 'records'
    self.timer.Start(10)
    time.sleep(10)

def add_record(self, event):
    while True:           
        for ch in range(0,8):
            Temp.append(get_temperature(ch))
        line = "Record %s" % self.index
        self.list_ctrl.InsertStringItem(self.index, line)
        add1 = self.list_ctrl.SetStringItem(self.index, 1, str(Temp[self.index]))
        for i in Temp:
            add1 += self.list_ctrl.SetStringItem(self.index, 1, str(Temp[self.index]))
        self.index += 1

【问题讨论】:

  • 你不能直接在wxpython中执行get_temperature(adc)使用wx.Timer()定期获取数据吗?
  • 不知道怎么实现。你能给我举个例子吗?
  • 我整天都在尝试,但我无法弄清楚。请帮帮我:)
  • 您希望它继续向列表中添加测量值还是继续更新列表中的第一项?为什么测量程序与 UI 分开?
  • 我想继续向列表中添加测量值。我编辑了我的代码。我得到一个控制台输出,但我需要它在 ListCtrl 中。我需要 10 秒的测量时间。

标签: python stream wxpython output stdout


【解决方案1】:

您需要创建一个 wx.Timer 并将其绑定到将更新列表控件的事件,将其添加到框架的 init 方法的末尾

TIMER_ID = wx.NewId()
self.timer = wx.Timer(id=TIMER_ID)
self.Bind(wx.EVT_TIMER, self.on_timer, id=TIMER_ID)
self.timer.Start(10*1000)


def on_timer(self, event):
    self.add_records()


def add_records(self):
    for ch in range(0, 8):
        temp = get_temperature(ch)
        line = "Record %s" % self.index
        self.list_ctrl.InsertStringItem(self.index, line)
        self.list_ctrl.SetStringItem(self.index, 1, temp)
        self.index += 1

【讨论】:

  • 谢谢,但我仍然得到 TypeError: 'Timer' object is not callable
  • 这应该不能正常工作:time.sleep 将阻止 wx 事件循环运行。请参阅long running tasks 如何通过分离线程来处理阻塞任务。
  • 哎呀,当我回答这个问题时,我显然分心了
  • 有人可以修吗?
  • 是的,现在我的列表超出了范围。
猜你喜欢
  • 2015-11-06
  • 2019-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 2019-07-10
相关资源
最近更新 更多