2012-08-27 16 views
5

kullanarak wxBitmaps sorunlarını görüntüleme Yazdığım bir programla ilgili bazı sorunlar yaşıyorum ve bazı yardım veya girişleri takdir ediyorum. Bazı arka plan için, bir web kamerası istemci yapmak için Python 2.7 ve wxPython kullanıyorum. İstemci görüntüleri sunucudan kendi iş parçacığına alır ve onları bir Kuyruğa yerleştirir. GUI iş parçacığı daha sonra bu görüntüleri sıradan alır ve bunları wxBitmap nesnesine dönüştürür. Bu her 5 saniyede olur ve sadece harika çalışır. wxBitmap nesnesini bir dosya olarak kaydedebilmem için her şeyin düzgün çalıştığını biliyorum.wxPython

Yapmakta olduğum sorun, GUI'mde görünmesi için wxBitmap nesnesinin gerçekten alınıyor olmasıdır. GUI'yi yapabildiğim tek şey, web kamerası görüntüsünün olması gereken gri bir dikdörtgen göstermektir.

İşte ekranını yenilemek istediğinizde denir benim onPaint() geçerli:

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) 

Basitçe söylemek gerekirse, ben niye onun çalışmıyor için bir kayıp değilim. araştırmalarımdan bir pencere makinesindeyim çünkü BeginDrawing() ve EndDrawing() işlevlerine ihtiyacım olduğunu buldum, bu yüzden onları ekledim. Hala çalışmıyor. Atılma hatası veya istisna yoktur. Ben wxFrame nesneyi güncelliyorum

  • : Bu sorunu çözmeye yardımcı olabilir

    diğer sorular. Belki wxPaintDC çalışmak için başka bir kapsayıcıda çalışması gerekiyor?

  • ?

Aslında, belki de benim __init__ işlevim, sorunu elinde tutan şeydir. Bunu düzgün bir şekilde mi ayarlıyorum?

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

Neyse, yardımlarınız için şimdiden teşekkürler.

DÜZENLEME: self.pnl = wx.Panel(self) numaralı satırı silerek sorunu yanlışlıkla çözdüm.

Görünüşe göre düzgün bir şekilde görüntüleniyordu, ancak bitmap panelin altındaydı. Olabilir? Gerçekten emin değilim. Bu wxPython olayında yeniyim.

+1

Panelin altında görünen görüntü bir olasılıktır. Açıkça bir "wx.Sizer" kullanım konumunu ayarlamadığınız sürece, nesneler varsayılan olarak (0,0) olarak ayarlanır. Bu yüzden sadece 1 öğem olsa bile bir boyut kullanıyorum. – acattle

cevap

1

Bu, wxPython demosunun da yaptığı gibi görünüyor: dc.DrawBitmap. Ve Windows üzerinde çalışıyor! En azından, AlphaDrawing demosunda yaptıkları şey bu. DrawImage demosunda dc.Blit() kullanırlar. Bunu deneyebilirsin.

Ancak, photo viewer ile yaptığım gibi yapamayacağımı merak ediyorum. DC'leri çizim yapmak için kullanmıyorum, ancak yalnızca güncellediğim bir wx.StaticBitmap kullanın.

+0

Bu soruyu sormadan önce fotoğraf görüntüleyici için kodunuza bakmıştım. Bakmıştım ki işe yaramazdı. WxPython'un ekrana nasıl bir şey yaptığını anladığımda muhtemelen bir kusur vardır ve bunun wx.App, wx.Frame ve wx.Panel'in birlikte nasıl çalıştığını düşünmek zorunda olduğunu düşünüyorum. Fotoğraf görüntüleyici için kodunuzun bir wx.Sizer ve wx.Widgets olduğunu, benim bir wx.App içinde olan bir wx.Frame içinde olan bir wx.Panel içinde, içinde sadece bir wx. Çerçeve ve bir dc nesnesi. Kodumu sizinkine benzeyecek şekilde yeniden yapılandırmaya ve size geri dönmeye çalışacağım. – user1626536

+0

Tamam. Küçük bir runnable örneği görmek güzel olurdu. Bu muazzam yardımcı olur. –

+0

burada çalışan yeni kodum. onun blogunuzdaki örneğe dayanarak, resim görüntüleyici. Çalıştığı için mutluyum, ama her yenilendiğinde titremeden mutlu değilim. Oh iyi. Bir hatayı çöz ve sanırım başka bir tane yarat. kodu heres: edit: yorum olarak bırakmak için çok fazla karakter. http://pastebin.com/WwHhTUAQ – user1626536

1

Bu kod çalışıyor. Her seferinde görüntüleri görüntüler. Gerçi, 'titreşim' eğilimindedir. Bu yüzden muhtemelen farkında olmadığım bir şey yapmanın daha iyi bir yolu var.

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() 
İlgili konular