5

私が書いているプログラムでいくつかの問題が発生しているので、助けや入力をいただければ幸いです。いくつかの背景として、ストリーミングWebカメラクライアントを実行するためにPython2.7とwxPythonを使用しています。クライアントは、サーバーから独自のスレッドで画像を取得し、それらをキューに入れます。次に、GUIスレッドはそれらの画像をキューから取得し、それらをwxBitmapオブジェクトに変換します。これは0.5秒ごとに発生し、うまく機能します。オブジェクトをファイルとして保存できるwxBitmapので、すべてが正常に機能していることがわかります。

私が抱えている問題は、実際にwxBitmapオブジェクトをGUIに表示させることです。GUIにできるように見えるのは、Webカメラの画像があるはずの場所に灰色の長方形を表示することだけです。

onPaint()画面を更新したいときに呼び出されるのは次のとおりです。

    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)

簡単に言えば、なぜそれが機能しないのか私は途方に暮れています。調査の結果、Windowsマシンを使用しているため、BeginDrawing()EndDrawing()関数が必要であることがわかったので、それらを追加しました。それでも動作しません。スローされるエラーや例外はありません。

この問題の解決に役立つ可能性のあるその他の質問:

  • オブジェクトを更新していwxFrameます。たぶん、wxPaintDC動作するために別のタイプのコンテナで動作する必要がありますか?

実際、私の__init__機能は問題を抱えているものかもしれません。これを正しく設定していますか?

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()

とにかく、よろしくお願いします。

編集:行を削除して、誤って問題を解決しましたself.pnl = wx.Panel(self)

どうやらそれは適切にレンダリングされていたようですが、ビットマップはパネルの下にありました。多分?よくわかりません。私はこのwxPython全体に不慣れです。

4

3 に答える 3

1

これは、wxPythonデモでも行われているようです:dc.DrawBitmap。そしてそれはWindowsで動作します!少なくとも、それは彼らがAlphaDrawingデモで行うことです。DrawImageデモでは、dc.Blit()を使用します。あなたはそれを試すかもしれません。

でも、フォトビューアーのようにできなかったのかな。DCを使用して描画するのではなく、更新したwx.StaticBitmapを使用します。

于 2012-08-27T14:32:26.763 に答える
1

このコードは機能します。毎回画像が表示されます。ただし、「ちらつき」する傾向があります。ですから、私が気付いていない、これを行うためのより良い方法があるでしょう。

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()
于 2012-08-27T23:24:53.237 に答える
0

数時間後、私が持っていた別の質問を調べて、私はこれを見つけました:

2つのPIL画像間の動きを検出する方法は?(wxPython Webカメラ統合の例が含まれています)

これには、美しく機能するサンプルコードが含まれています。

于 2012-08-28T01:12:54.220 に答える