【问题标题】:how to display and dynamically update multiple wxpython static text with data from a mcp3008?如何使用来自 mcp3008 的数据显示和动态更新多个 wxpython 静态文本?
【发布时间】:2017-03-09 14:39:31
【问题描述】:

我有一个 python 程序,它从 mcp3008 和雨水传感器获取数据。我想使用 wxpython 在 gui 中显示它。这是我的传感器程序:

import spidev
from time import sleep
import os

spi = spidev.SpiDev()
spi.open(0,0)

def getAdc (channel):
    if ((channel>7)or(channel<0)):
        return -1

    r = spi.xfer2([1, (8+channel) << 4, 0])

    adcOut = ((r[1]&3) << 8) + r[2]
    percent = int(round(adcOut/10.24))
    volts = ((adcOut/1023) * 5)
    if adcOut >= 0 and adcOut <= 300:
            print "--------------------------------------------------------------"
            print ("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
            print ("Rain Condition : Heavy Rain")
            sleep(5)

    elif adcOut >= 0 and adcOut <= 500:
            print "--------------------------------------------------------------"
            print ("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
            print ("Rain Condition : Moderate Rain")
            sleep(5)

    elif adcOut >= 0 and adcOut <= 700:
            print "--------------------------------------------------------------"
            print ("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
            print ("Rain Condition : Light Rain")
            sleep(5)

    else :
            print "--------------------------------------------------------------"
            print ("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
            print ("Rain Condition : No Rain")
            sleep(5)
while True:
    getAdc(0)

这是我创建的用于显示它的 wxpython 程序。帮我看看如何将这两个程序合二为一来显示数据。

import datetime

global current_time
current_time = datetime.datetime.strftime(datetime.datetime.now(), '%d-%m-%y    %H:%M:%S')

try:
    import wx
except ImportError:
    raise ImportError, "The wxPython module is required to run this program."

class RainSensorApp_wx(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, size = (500, 300))
        self.SetBackgroundColour(wx.BLUE)
        self.parent = parent
        self.initialize()

    def initialize(self):
        sizer = wx.GridBagSizer()
        font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
        self.SetFont(font)

        self.label = wx.StaticText(self, -1, label = u'Rain Sensor Level:   {0:4d}  Percentage:     {1:3}%  Voltage:    {2} V'.format(adcOut, percent, volts))
        self.label.SetBackgroundColour(wx.BLUE)
        self.label.SetForegroundColour(wx.WHITE)
        sizer.Add(self.label, (1,0), (1,2), wx.EXPAND)

        self.label = wx.StaticText(self, -1, label = u'Rain Condition:  {}'.format(rain_condition))
        self.label.SetBackgroundColour(wx.BLUE)
        self.label.SetForegroundColour(wx.WHITE)
        sizer.Add(self.label, (2,0), (1,3), wx.EXPAND)

        self.label = wx.StaticText(self, -1, label = u'Time Updated: {}'.format(current_time))
        self.label.SetBackgroundColour(wx.BLUE)
        self.label.SetForegroundColour(wx.WHITE)
        sizer.Add(self.label, (3,0), (1,4), wx.EXPAND)

        self.SetSizer(sizer)
        self.Show(True)

    def on_timer(self):
        wx.CallLater(1000, self.on_timer)

if __name__ == "__main__":
    app = wx.App()
    frame = RainSensorApp_wx(None, -1, 'Rain Sensor Monitor')
    app.Mainloop()
    getAdc(0)

在此之后,我将使用 CallLater 添加计时器,以动态更新多个 wxpython 静态文本,因为我昨天刚刚学习它。感谢谁会帮助我并阅读我的帖子。

【问题讨论】:

    标签: python wxpython


    【解决方案1】:

    这有点小技巧,因为我必须模拟 spidev 位,但这应该足以让您入门。
    代码记录在我认为重要的地方。

    import datetime
    #import spidev
    from time import sleep
    import os
    
    #spi = spidev.SpiDev()
    #spi.open(0,0)
    #Setup some variables as I don't have spidev
    global adcOut
    adcOut = 200
    percent = int(round(adcOut/10.24))
    volts = ((adcOut/1023) * 5)
    rain_condition="none"
    
    global current_time
    current_time = datetime.datetime.strftime(datetime.datetime.now(), '%d-%m-%y    %H:%M:%S')
    
    try:
        import wx
    except ImportError:
        raise ImportError, "The wxPython module is required to run this program."
    
    class RainSensorApp_wx(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, size = (500, 300))
            self.SetBackgroundColour(wx.BLUE)
            self.parent = parent
            self.initialize()
    
        def initialize(self):
            sizer = wx.GridBagSizer()
            font = wx.Font(20, wx.DECORATIVE, wx.ITALIC, wx.NORMAL)
            self.SetFont(font)
            self.label1 = wx.StaticText(self, -1, label = u'Rain Sensor Level:   {0:4d}  Percentage:     {1:3}%  Voltage:    {2} V'.format(adcOut, percent, volts))
    
            #Give the labels unique names
    
            self.label1.SetBackgroundColour(wx.BLUE)
            self.label1.SetForegroundColour(wx.WHITE)
            sizer.Add(self.label1, (1,0), (1,2), wx.EXPAND)
    
            self.label2 = wx.StaticText(self, -1, label = u'Rain Condition:  {}'.format(rain_condition))
            self.label2.SetBackgroundColour(wx.BLUE)
            self.label2.SetForegroundColour(wx.WHITE)
            sizer.Add(self.label2, (2,0), (1,3), wx.EXPAND)
    
            self.label3 = wx.StaticText(self, -1, label = u'Time Updated: {}'.format(current_time))
            self.label3.SetBackgroundColour(wx.BLUE)
            self.label3.SetForegroundColour(wx.WHITE)
            sizer.Add(self.label3, (3,0), (1,4), wx.EXPAND)
    
        #Create a timer and perform on_timer every 1000 milliseconds(change to 5000)
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.on_timer, self.timer)
            self.timer.Start(1000)
    
            self.SetSizer(sizer)
            self.Show(True)
    
        def on_timer(self,event):
            channel = 0
            if ((channel>7)or(channel<0)):
                return -1
        #Hack out spidev references and use globals to emulate something happening
    
    #        r = spi.xfer2([1, (8+channel) << 4, 0])
    #        adcOut = ((r[1]&3) << 8) + r[2]
    
            global adcOut
            adcOut = adcOut +1
            percent = int(round(adcOut/10.24))
            volts = ((adcOut/1023) * 5)
            if adcOut >= 0 and adcOut <= 300:
    
            # Update the screen output 
    
                    self.label1.SetLabel("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
                    self.label2.SetLabel("Rain Condition : Heavy Rain")
    
            elif adcOut >= 0 and adcOut <= 500:
                    self.label1.SetLabel("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
                    self.label2.SetLabel("Rain Condition : Moderate Rain")
    
            elif adcOut >= 0 and adcOut <= 700:
                    self.label1.SetLabel("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
                    self.label2.SetLabel("Rain Condition : Light Rain")
    
            else :
                    self.lable1.SetLabel("ADC Output:     {0:4d}  Percentage: {1:3}%  Voltage : {2} V".format(adcOut,percent,volts))
                    self.lable2.SetLabel("Rain Condition : No Rain")
    
    if __name__ == "__main__":
        Rs = wx.App()
        RainSensorApp_wx(None, -1, 'Rain Sensor Monitor')
        Rs.MainLoop()
    

    【讨论】:

    • 感谢您的回答。我将在这个星期二为您提供解决方案,并在测试后提供有关它的更新。如果有人有其他答案,我欢迎它,因为我得到的解决方案越多,我得到的答案就越成功。
    • 我已经尝试了您的代码并且它正在工作,除了它在 gui 程序启动之前在 python 2.7.10 shell 中给出(SyntaxWarning: name 'adcOut' is assigned to before global declaration)。我还对伏特代码进行了细微更改,以两位小数显示,并添加 self.label3.SetLabel("Time Updated: {}".format(current_time) 与全局 current_time 并在您忘记更新时初始化 current_time时间
    • 如答案中所述,“足以让您入门”。为了解决我无法访问“mcp3008 和雨水传感器”的事实,这有点小题大做。至于更新格式和时间问题,您的原始代码没有包含它们,我不是读心者。除此之外,我们非常欢迎您。
    • 很抱歉没有 SyntaxError。它显示是因为我在计时器代码处将 # 放在全局 adcOut 前面。但我有一个问题,为什么你把 adcOut = adcOut + 1 放在“全局 adcOut”下面。
    • @anubismmt 这只是为了模拟变化的电压,因为我没有传感器。我用它来测试“雨况”是否随时间变化。它对你的代码没有用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多