У меня есть простое приложение, которое отображает список пользовательских сведений в wx.VListBox Каждый элемент отображается с помощью OnDrawItem(), и все работает отлично, когда мне нужно нарисовать текст, линию или изображение.Нарисуйте пользовательскую панель с контролем в wx.VListBox OnDrawItem()
Приложение вид:
Как добавить около нескольких текстовых меток (имя и адрес электронной почты) также несколько wx.ComboBox, несколько wx.ComboBox в каждой строке?
Я рассматриваю решение как визуализацию некоторого пользовательского элемента управления на основе wx.Panel, который имеет все элементы управления, установленные на этой панели, но как визуализировать панель с ее дочерними элементами управления в каждой строке wx.VListBox?
Мой текущий полный код (просто скопировать/вставить):
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()
Спасибо, имеет смысл. Но как отслеживать клики/зависание этого конкретного изображения по всей ячейке списка? И еще более интересно - как на месте это изображение с реальным управлением в тех же координатах и снова удалять управление. Можете ли вы предложить любое место с образцом кода? – Zelid
Вы можете привязываться к событию перемещения мыши и использовать 'VirtualHitTest()', чтобы получить элемент под ним, но поиск точного местоположения комбо-кнопки может оказаться сложным, если вы можете просто полностью перекрывать ячейку с помощью реального combobox, это было бы самым простым решением. Удаление элемента управления просто: просто сделайте это, когда он потеряет фокус. –