StaticBitmap not refreshing

23 views
Skip to first unread message

toma...@gmail.com

unread,
Feb 15, 2018, 9:36:39 AM2/15/18
to wxPython-users
Hi All
I finally got my timer to work. The code queries a database and does a count on the result.
If the count is equal to 62 the script outputs a green traffic light on a panel, else it is MEANT to output a red traffic light image.

At the moment it only outputs either the red or green traffic light ... It doesn't update once the first image is presented.

Can anyone advise as to why this is



import wx
import cx_Oracle
import re



class Example(wx.Frame):
    def __init__(self, parent, title):
        super(Example, self).__init__(parent, title=title, size=(1600, 900))
        self.basicGUI()

    def basicGUI(self):
        menuBar = wx.MenuBar()
        fileButton = wx.Menu()
        exitItem = fileButton.Append(wx.ID_EXIT,'Exit')
        menuBar.Append(fileButton,'File')
        self.SetMenuBar(menuBar)
        self.Bind(wx.EVT_MENU,self.Quit,exitItem)
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        self.timer.Start(1000)
        
    def OnTimer(self, event):
        greenimage = 'E:\folder\folder\folder\Traffic_Light\green.jpg'
        amberimage = 'E:\folder\folder\folder\Traffic_Light\amber.jpg'
        redimage = 'E:\folder\folder\folder\Traffic_Light\red.jpg'
        green = wx.Image(greenimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        amber = wx.Image(amberimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        red = wx.Image(redimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        panel = wx.Panel(self)
        def services():
            c = cx_Oracle.connect("user/password@SID")
            cursor = c.cursor()
            running_sn = cursor.execute("select count(*) from table1 J, table2 s where j.table1 = s.table2 and s.table2 IS NULL")
            for running_sn in cursor:
                running_sn = str(running_sn)
                running_sn = re.sub(r'[^w]', '', running_sn)
                return running_sn
        if services() == '62':
            print services()
            wx.StaticBitmap(panel, -1, green, (90, 60))
        else:
            print services()
            wx.StaticBitmap(panel, -1, red, (90, 30))
        wx.StaticBitmap(panel, -1)

        self.Show()

    def Quit(self, e):
        self.Close()



def main():
    app = wx.App()
    Example(None, title='Health Checks')
    app.MainLoop()

main() 



Chris Barker

unread,
Feb 15, 2018, 1:46:13 PM2/15/18
to wxpython-users
First:

it's best to post a small self contained example -- you almos hvae that, but you cant' run with code witout the DB -- and I'm not going to take the time to rip out that part :-) -- that is, the easier you make it for others to run your example, the more likely they will and then they can fix your problem.

But:

1) you may need a .Refresh() and/or Update() in there to see the changes.

2) you probably don't want to create new StaticBitmaps every time the timer goes off -- rather, you can change the image in the bitmap. Here's an example:


(that's old code, so may need some tweaking, but the idea should still be good.)


Also, I imagine this is sample code, but you probably don't want to load the images from disk each time the time goes off, etiher...

-CHB


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris....@noaa.gov

Tim Roberts

unread,
Feb 15, 2018, 5:34:55 PM2/15/18
to wxpytho...@googlegroups.com
toma...@gmail.com wrote:
>
> I finally got my timer to work. The code queries a database and does a
> count on the result.
> If the count is equal to 62 the script outputs a green traffic light
> on a panel, else it is MEANT to output a red traffic light image.
>
> At the moment it only outputs either the red or green traffic light
> ... It doesn't update once the first image is presented.
>
> Can anyone advise as to why this is

I need to present a little critique of your code.  You have some
problems here.

    def OnTimer(self, event):
        greenimage = 'E:\folder\folder\folder\Traffic_Light\green.jpg'
        amberimage = 'E:\folder\folder\folder\Traffic_Light\amber.jpg'
        redimage = 'E:\folder\folder\folder\Traffic_Light\red.jpg'

This can't be the actual code you used.  You can't write paths with
backslashes like that.  In this specific case, that "\r" is the one
character "carriage return" (chr(15)), not the two characters you
think.  When writing DOS paths, you have three choices:  double the
backslashes, raw strings, or forward slashes:

        redimage = 'E:\\folder\\folder\\folder\\Traffic_Light\\red.jpg'
        redimage = r'E:\folder\folder\folder\Traffic_Light\red.jpg'
        redimage = 'E:/folder/folder/folder/Traffic_Light/red.jpg'

And yes, EVERY Windows API that accepts a file name will accept either
forward or backward slashes.  The only place you can't use them is in a
command shell.

        green = wx.Image(greenimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        amber = wx.Image(amberimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        red = wx.Image(redimage, wx.BITMAP_TYPE_ANY).ConvertToBitmap()

All of that should be in your __init__, with the images stored in
members, like "self.green".  As you have it written you will load and
convert those bitmap files every time the timer fires -- once a second.

        panel = wx.Panel(self)

Same comment.  You are creating a new panel every second and placing
your static bitmap on that new panel.  You're going to end up with a LOT
of panels, but only the first one is going to fill the frame.  You need
to move this to your "basicGUI" and save the panel handle in a member
variable.

        def services():
            c = cx_Oracle.connect("user/password@SID")
            cursor = c.cursor()
            running_sn = cursor.execute("select count(*) from table1 J,
table2 s where j.table1 = s.table2 and s.table2 IS NULL")
            for running_sn in cursor:
                running_sn = str(running_sn)
                running_sn = re.sub(r'[^w]', '', running_sn)
                return running_sn

I don't understand why you made this an inline function, unless you
expect to make it separate later on.  You could have just done this all
inline.

Your SQL is wrong.  Did you retype this in a strange attempt at secrecy?

You shouldn't need the "str" and the regular expression stuff.  The
"cursor.execute" returns a list of lists of field values.  Since there
us only one record and that record only has one value, you can eliminate
the loop just say:  return cursor.fetchone()[0].

        if services() == '62':
            print services()
            wx.StaticBitmap(panel, -1, green, (90, 60))
        else:
            print services()
            wx.StaticBitmap(panel, -1, red, (90, 30))

Every call to services() is another database connection.  You should
call it once and save the value.  And both of these are create a NEW
static bitmap, part of the new panel you are creating once a second. 
You just need to replace the bitmap in the existing StaticBitmap.

        wx.StaticBitmap(panel, -1)

I can't imagine what you thought this was doing.  What it actually does
is create ANOTHER new StaticBitmap as a child of the new panel.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Reply all
Reply to author
Forward
0 new messages