WxPython, привязка события двойного щелчка к определенному списку, в отличие от всех

В настоящее время я создаю графический интерфейс, и я использую список, пользователь дважды щелкнет элемент в списке, и выбранный элемент будет передан коду. Это работает нормально, но проблема, с которой я сталкиваюсь, заключается в том, что я не могу связать событие DoubleClick с одним списком, я просто получаю ошибки, и программа не запускается всякий раз, когда я пытаюсь добавить идентификатор.

Код, который работает, но без идентификатора:

serverlistbox=wx.ListBox(panel1, -1, (300,80), (180,180), serverfilelist, wx.LB_SINGLE)
serverlistbox.SetSelection(0)

self.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick)

И функция, которая обрабатывает данные:

 def doubleclick(self,event):
    index = event.GetSelection()
    downloadselect = serverfilelist[index]
    wx.MessageBox('Starting download of ' +str(serverfilelist[index]))

Таким образом, EVT является важным битом, я хочу связать его ТОЛЬКО с полем списка серверов, в отличие от всех моих списков. Я пробовал:

self.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick, self.serverlistbox)
self.Bind(wx.EVT_LISTBOX_DCLICK, self.serverlistbox, self.doubleclick)
self.Bind(wx.EVT_LISTBOX_DCLICK, -1, self.doubleclick)

Все вышеперечисленное терпит неудачу. Пожалуйста помоги!!!


person Xerphiel    schedule 22.01.2012    source источник
comment
Трудно отладить это, не зная, например. что такое self и т. д., или увидеть Traceback. Не могли бы вы опубликовать работающий минимальный пример.   -  person tom10    schedule 22.01.2012


Ответы (3)


ваш первый вариант должен работать:

self.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick, self.serverlistbox)

У вас есть некоторые проблемы, которые приводят к сбою кода: вы индексируете serverfilelist в методе doubleclick. Однако этот список недоступен внутри метода. Вероятно, вы должны сделать что-то вроде:

self.serverfilelist = serverfilelist
self.serverlistbox = wx.ListBox(panel1, -1, (300,80), (180,180), self.serverfilelist, wx.LB_SINGLE)
self.serverlistbox.SetSelection(0)

self.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick, self.serverlistbox)

def doubleclick(self, event):
    index = event.GetSelection()
    downloadselect = self.serverfilelist[index]
    wx.MessageBox('Starting download of %s' % str(downloadselect)

Также, если вы создаете serverlistbox как атрибут класса:

self.serverlistbox = wx.ListBox(panel1, ....  

тогда вы можете напрямую вызвать self.serverlistbox.GetSelection в методе, не используя событие.

Однако я рекомендую использовать:

downloadselect = self.serverlistbox.GetStringSelection()

Затем ваш метод упрощается до:

def doubleclick(self, event):
    downloadselect = self.serverlistbox.GetStringSelection()
    wx.MessageBox('Starting download of %s' % downloadselect
person joaquin    schedule 22.01.2012

Можете ли вы привязаться к списку (вместо того, что есть self)? Что-то типа:

self.serverlistbox.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick)

(Если это не делает то, что вы хотите, было бы полезно получить дополнительную информацию, особенно опубликовать Traceback и наименьший возможный фрагмент кода, который работает, но все еще показывает ошибку.)

person tom10    schedule 22.01.2012

Предыдущие сообщения направляют вас к решению, но могут быть некоторые другие моменты, которые можно уточнить, в чем может быть проблема.

События wx обрабатываются через иерархию объектов Python. Поэтому, если тип события привязан к, но кодер не знает, где событие заканчивается, вы можете не передать событие обработчику событий. В вашей линии

self.Bind(wx.EVT_LISTBOX_DCLICK, self.doubleclick, self.serverlistbox)

вы не можете сказать, кто является родительским виджетом self.serverlistbox. В одном из приведенных выше примеров родительским элементом является «panel1». Был ли у Panel1 обработчик EVT_LISTBOX_DCLICK? Этот обработчик передал событие своему родителю? Вы использовали для этого event.Skip()?

Существует не только проблема ссылки на объекты Python вне области действия, что делает полезную трассировку/исключение, но также существует проблема того, какой виджет получает событие и передается ли событие объекту с ограниченным обработчиком событий.

Вот пример, который может помочь показать обработчик событий распространения/правильно ограниченного, устраняющий проблемы с областью действия Python:

#
# http://stackoverflow.com/questions/8960808/wxpython-linking-a-double-click-event-to-specific-list-boxs-opposed-to-all

import sys
import wx

__doc__ = """Usage:
python.exe doubleclic.py
python.exe doubleclic.py panel
python.exe doubleclic.py panel frame
"""

def OnDoubleClick_ListBox_Widget_Handler(event):
    textctrl.AppendText('\nListBox: ' + event.GetString() + '\n')
    if 'panel' in sys.argv: event.Skip()

def OnDoubleClick_Panel_Widget_Handler(event):
    game_selected = listbox.GetStringSelection()
    textctrl.AppendText('Panel: ' + event.GetString() + '\n')
    if 'panel' in sys.argv and 'frame' in sys.argv: event.Skip()

def OnDoubleClick_Frame_Widget_Handler(event):
    game_selected = listbox.GetStringSelection()
    textctrl.AppendText('Frame: ' + event.GetString() + '\n')


if __name__ == "__main__":
    app = wx.App()
    frame = wx.Frame(None, title="Demo wx.EVT_LISTBOX_DCLICK event binding and propogation")
    panel = wx.Panel(frame)

    listbox = wx.ListBox(panel, choices=['rock', 'paper', 'scissor'], name='ListBox')
    textctrl = wx.TextCtrl(panel, style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_DONTWRAP, name='Wrong Widget')
    textctrl.AppendText(__doc__)
    textctrl.AppendText("command line given: \n   " + ' '.join(sys.argv) + '\n\n')

    sizer = wx.BoxSizer(wx.HORIZONTAL)
    sizer.Add(listbox, 0, wx.EXPAND|wx.ALL)
    sizer.Add(textctrl, 1, wx.EXPAND|wx.ALL)
    panel.SetSizer(sizer)

    listbox.Bind(wx.EVT_LISTBOX_DCLICK, OnDoubleClick_ListBox_Widget_Handler)
    panel.Bind(wx.EVT_LISTBOX_DCLICK, OnDoubleClick_Panel_Widget_Handler)
    frame.Bind(wx.EVT_LISTBOX_DCLICK, OnDoubleClick_Frame_Widget_Handler)

    frame.Show()
    app.MainLoop()

Надеюсь, это поможет тем, кто придет к этой проблеме намного позже после первоначального поста.

person DevPlayer    schedule 01.12.2014