Problems displaying wxBitmaps using wxPython

I am having problems with the program I am writing, and I would appreciate some help or input. For some background, I use Python 2.7 and wxPython in order to make the webcam client streamed. The client receives images from the server in its stream and puts them in the queue. The GUI thread then receives these images from the queue and converts them into an object wxBitmap. This happens every 0.5 seconds and works great. I can save the object wxBitmapas a file so that I know that everything is working correctly.

The problem I am facing is that the object is wxBitmapdisplayed in my GUI. The only thing I can do to make the GUI is to show the gray rectangle where the webcam image should be.

Here is mine onPaint()that gets called when I want to refresh the screen:

    def onPaint(self,e):
            ## this is the function that actually draws and redraws the window
            ## to be displayed. I think it is something similar to blit()
            ## in other graphical display frameworks
            print "in onPaint"

            ## create the device context object (graphics painter)
            dc = wx.PaintDC(self)
            dc.BeginDrawing()

            ## draw the bitmap to the screen
            dc.DrawBitmap(self.imageBit,0,0,True)
            dc.EndDrawing()            

            ## test code.
            ## the following works and updates, which means that
            ## everything is being converted properly and updated.
            ## not sure why the dc won't paint it to the window. 
            self.imageBit.SaveFile("bit.bmp", wx.BITMAP_TYPE_BMP)

Simply put, I do not understand why it does not work. from my research, I found that since I am on a Windows machine, I need functions BeginDrawing()and EndDrawing()therefore I added them. Still not working. No errors or exceptions.

Other issues that may help solve this problem:

  • I am updating an object wxFrame. Maybe it wxPaintDCshould work in a container of a different type?
  • ?

Actually, maybe my function __init__is the problem. Am I setting it right?

class viewWindow(wx.Frame):
    imgSizer = (480,360)
    def __init__(self, *args, **kw):
            ## this is called when an instance of this class is created
            super(viewWindow,self).__init__(*args,**kw)

            ## here is where the actual stuff inside the frame is set up.

            self.pnl = wx.Panel(self)

            ## create a button that opens up a Connection Window
            #test = wx.Button(self.pnl, label='Connection Settings')
            ## test.Bind(wx.EVT_BUTTON, self.openConnectionWindow)

            ## create the wxImage for the web cam pic
            self.image = wx.EmptyImage(self.imgSizer[0],self.imgSizer[1])

            ## create the wxBitmap so that the wxImage can be displayed
            self.imageBit = wx.BitmapFromImage(self.image)

            ## create a timer that will update the window based of frame rate
            self.timex = wx.Timer(self, wx.ID_OK)
            self.timex.Start(500)
            self.Bind(wx.EVT_TIMER, self.redraw, self.timex)

            ## need to do the following in order to display images in wxPython:
            self.Bind(wx.EVT_PAINT, self.onPaint)

            self.SetSize(self.imgSizer)
            self.SetTitle('View Window')
            self.Show()

, .

EDIT: , self.pnl = wx.Panel(self).

, , . ? . wxPython.

+5
3
0

, - wxPython: dc.DrawBitmap. Windows! , , - AlphaDrawing. DrawImage dc.Blit(). .

, , , . DC , wx.StaticBitmap, .

+1

This code works. It displays images every time and all that. However, this tends to flicker. Therefore, probably the best way to do this that I do not know about.

class viewWindow(wx.Frame):
    imgSizer = (480,360)
    def __init__(self, parent, title="View Window"):
            super(viewWindow,self).__init__(parent)
            ## create the menu and its sub trees
            menubar = wx.MenuBar()
            filemenu = wx.Menu()
            menubar.Append(filemenu, 'File')
            self.fitem = filemenu.Append(wx.ID_ANY, 'Open Connection Window')
            self.Bind(wx.EVT_MENU, self.openConnectionWindow, self.fitem)
            self.SetMenuBar(menubar)

            ## here is where the actual stuff inside the frame is set up.
            self.pnl = wx.Panel(self)
            self.vbox = wx.BoxSizer(wx.VERTICAL)

            ## create the wxImage for the web cam pic
            self.image = wx.EmptyImage(self.imgSizer[0],self.imgSizer[1])

            ## create the wxBitmap so that the wxImage can be displayed
            self.imageBit = wx.BitmapFromImage(self.image)
            self.staticBit = wx.StaticBitmap(self.pnl,wx.ID_ANY, self.imageBit)

            ## add the staticBit to the sizer so it is rendered properly on resizes and such
            ## note: not actually needed to get the image to display, but reccommended for ease
            ## of layout
            self.vbox.Add(self.staticBit)

            ## register the sizer with the panel so the panel knows to use it.
            self.pnl.SetSizer(self.vbox)

            ## create a timer that will update the window based on frame rate
            self.timex = wx.Timer(self, wx.ID_OK)
            self.timex.Start(1000/framerate)
            self.Bind(wx.EVT_TIMER, self.redraw, self.timex)

            ## set the size of the frame itself when it is first opened
            self.SetSize(self.imgSizer)
            self.Show()

    def openConnectionWindow(self, e):
            ## this will open a new connection window
            connect = connectionWindow(None)

    def redraw(self,e):
            ## this function updates the frame with the latest web cam image that has been
            ## retrieved by the client thread from the server.

            ## get the newest image in the queue 
            if not imgQ.empty():                        
                    picz = imgQ.get()
                    ## convert the image from a string to something usable (wxImage)
                    self.image.SetData(picz)
                    ## from wxImage to wxBitmap
                    self.imageBit = wx.BitmapFromImage(self.image)
                    self.staticBit = wx.StaticBitmap(self.pnl,wx.ID_ANY, self.imageBit)
                    ## refresh the frame
                    self.Refresh()
+1
source

All Articles