2016-04-10 16 views
0

wx.VListBox içinde kullanıcı bilgileri listesini gösteren basit bir uygulama var. Her öğe OnDrawItem() kullanılarak oluşturulur ve her şey iyi bir resim çizmem gerektiğinde çalışır. metin, çizgi veya görüntü.wx.VListBox OnDrawItem() denetimiyle özel paneli çizin

uygulama görünüm:

enter image description here

Nasıl her satır için birkaç metin etiketleri (isim ve e-posta) da yanında birkaç wx.ComboBox, birkaç wx.ComboBox eklenir?

Çözümü, o panelde tüm denetimlerin yer aldığı wx.Panel temelli bazı özel denetimler oluşturuyor, ancak wx.VListBox'ın her satırında alt denetimleriyle bir panelin nasıl oluşturulduğunu görüyorum?

Benim şu anki tam kodu (sadece kopyala/yapıştır):

import wx 


class UserInfo(object): 
    def __init__(self, name, email, *args, **kwargs): 
     super(self.__class__, self).__init__(*args, **kwargs) 

     self.name = name 
     self.email = email 


class UserListBox(wx.VListBox): 
    def __init__(self, parent, users, *args, **kwargs): 
     super(self.__class__, self).__init__(parent, *args, **kwargs) 

     self.bh = 10 
     self.users = users 

     self.SetItemCount(len(self.users)) 

    def OnMeasureItem(self, idx): 
     image_height = self.bh + 4 
     name_size = self.GetTextExtent(self.users[idx].name) 
     email_size = self.GetTextExtent(self.users[idx].email) 
     return max(image_height, name_size[1] + email_size[1] + 6) 

    def OnDrawSeparator(self, dc, rect, idx): 
     oldpen = dc.GetPen() 
     dc.SetPen(wx.Pen(wx.BLACK)) 
     dc.DrawLine(rect.x, rect.y, rect.x + rect.width, rect.y) 
     rect.Deflate(0, 2) 
     dc.SetPen(oldpen) 

    def OnDrawItem(self, dc, rect, n): 
     # Draw the name label to the right of the bitmap 
     textx = rect.x + 2 + self.bh + 2 
     lblrect = wx.Rect(textx, rect.y, 
          rect.width - textx, 
          rect.height) 
     user = self.users[n] 
     dc.DrawLabel(user.name, lblrect, 
        wx.ALIGN_LEFT | wx.ALIGN_TOP) 
     dc.DrawLabel(user.email, lblrect, 
        wx.ALIGN_LEFT | wx.ALIGN_BOTTOM) 


class AppFrame(wx.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     super(self.__class__, self).__init__(parent, *args, **kwargs) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     self.SetSizer(sizer) 

     users = list() 
     for n in range(100): 
      users.append(UserInfo('John %s' % n, '[email protected]')) 

     listobx = UserListBox(self, users, size=(150, 250), style=wx.BORDER_SUNKEN) 
     sizer.Add(listobx, flag=wx.EXPAND) 

     btn = wx.Button(self, label='Do it!') 
     sizer.Add(btn) 


class DemoApp(wx.App): 
    def OnInit(self): 
     self.frame = AppFrame(None, title="App Demo") 
     self.frame.Show() 
     return True 

if __name__ == '__main__': 
    app = DemoApp() 
    app.MainLoop() 

cevap

1

Sen özel denetimler, ör doğal görünümlü temsillerini çizmek wxRendererNative sınıfının yöntemlerini kullanabilirsiniz Senin durumunda DrawComboBoxDropButton() kullanmışsın. Görüntünün her tıkladığında (ya da farenin üzerine geldiğinde bile) gerçek bir wxComboBox oluşturmanız gerekir.

+0

Teşekkürler, mantıklı. Ancak tam liste kutusu hücresine belirli bir görüntüyü tıklatıp/izlemeyi nasıl izleyebilirsiniz? Ve daha da ilginç - aynı koordinatlarda gerçek kontrole sahip görüntüyü nasıl ve tekrar kontrolünü kaldır. Kod örneği ile herhangi bir yer önerebilir misin? – Zelid

+0

Fare hareket olayına bağlanabilir ve altındaki öğeyi almak için 'VirtualHitTest()' kullanabilir, ancak yalnızca gerçek combobox'la hücreyi tamamen kapatabilirseniz, açılan düğmenin tam yerini bulma zorluğu riskini alabilirsiniz. en basit çözüm olurdu. Kontrolün kaldırılması basittir: sadece odağı kaybettiğinde yapın. –