Search code examples
python-3.xwxpython

updating a wx MessageBox text


I'm reading a humidity/temperature sensor, and want to display the reading continuously (e.g. every 500ms) Currently, I can only update the output upon user click.

# -*- coding: utf-8 -*-
from Phidget22.Devices.TemperatureSensor import *
from Phidget22.Devices.HumiditySensor import *
from Phidget22.Net import *
import wx

temp = 0
humd = 0

ct = TemperatureSensor()
ch = HumiditySensor()


def read_sensor():
    global temp, humd
    try:
        ct.openWaitForAttachment(500)
        ch.openWaitForAttachment(500)

    except PhidgetException as e:
        print("Phidget Exception %i: %s" % (e.code, e.details))
        print("Press Enter to Exit...\n")
        readin = sys.stdin.read(1)
        exit(1)

    temp = ct.getTemperature()
    ct.close()
    humd = ch.getHumidity()
    ch.close()


app = wx.App()

# simple dialog
read_sensor()
win1 = wx.MessageBox('Temperature:   %0.2fC \n============\nHumidity:   %0.2f%%' % (temp, humd),         'Environment',wx.OK | wx.CANCEL)

while win1 != wx.CANCEL:
    read_sensor()
    win1 = wx.MessageBox('Temperature:   %0.2fC \n============\nHumidity:   %0.2f%%' % (temp, humd), 'Environment',wx.OK | wx.CANCEL)
if win1 == wx.CANCEL:
    exit(-2)

I see in the docs references to UpdateUI event, but I know not how to implement this in my code. The current code is wastefull, as it launches the window again and again, instead of simply updating the text (this causes resource waste as well).


Solution

  • Something simple like this, with a wx.Timer should get you started.

    import wx
    import random # testing only
    class MyFrame(wx.Frame):
        def __init__(self, parent, id=wx.ID_ANY, title=""):
            super(MyFrame, self).__init__(parent, id, title, size=(300,150))
            self.temp = 10
            self.humd = 75
            # Create a simple panel using positioned text widgets
            self.panel = wx.Panel(self)
            temp_lbl = wx.StaticText(self, label='Temperature:', pos=(20,10))
            humd_lbl = wx.StaticText(self, label='Humidity   :', pos=(20,50))
            self.disptemp = wx.StaticText(self, label="0", pos=(120,10))
            self.disphumd = wx.StaticText(self, label="0", pos=(120,50))
            self.exit = wx.Button(self, label="Stop", pos=(120,80))
    
            # Close routine if the Close X (top right corner) is clicked
            self.panel.Bind(wx.EVT_CLOSE, self.OnExit)
            self.exit.Bind(wx.EVT_BUTTON, self.OnExit)
    
            # Define a timer to run the OnTimer function every 500 micro seconds
            self.timer = wx.Timer(self)
            self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
            self.timer.Start(500)
            self.Show()
    
        def OnTimer(self, event):
            self.read_sensor()
    
        def read_sensor(self):
            #
            # call your sensor routine here updating self.time and self.humd
            # for testing purposes I simply increment hack them
            # You probably don't have to open and close each time
            # open on start| close on Exit and access with
            #    self.temp = ct.getTemperature()
            #    self.humd = ch.getHumidity()
            #
            self.temp = random.uniform(-20.0,50.0)
            self.humd = random.uniform(10.0,100.0)
    
            self.disptemp.SetLabel("%03.02f" % (self.temp))
            self.disphumd.SetLabel("%03.02f" % (self.humd))
    
        def OnExit(self, event):
            self.timer.Stop()
            self.Destroy()
    
    if __name__ == "__main__":
        app = wx.App()
        frame = MyFrame(None,title="Current Temperature/Humidity")
        app.MainLoop()
    

    enter image description here