2015-08-03 2 views
0

Я пишу суперкласс, у которого есть код для создания контекстного меню при щелчке правой кнопкой мыши на определенной кнопке.Каков наилучший способ добавить расширяемость к действиям класса в python

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

Что такое самый гладкий способ сделать это в python?

def context_menu(self, image_name, event): 
    menu = Tk.Menu(self.root, tearoff=0) 
    menu.add_command(label="Copy Image Path", command= lambda name=image_name: self.to_clipboard(name)) 
    ## TODO add the ability to neatly add context options when defining a subclass. 
    #for label, action in cls.context_options: 
    # menu.add(label=label, command=action(image_name)) 
    menu.post(event.x_root, event.y_root) 

ответ

0

Очень простой способ:

class AbstractMenu: 
    def __init__(self, root): 
     self.menu = Tk.Menu(root, tearoff=0) 

    def post(self, event): 
     self.menu.post(event.x_root, event.y_root) 


class BaseMenu(AbstractMenu): 
    def __init__(self, root, image_name): 
     super().__init__(root) 
     self.menu.add_command(label="Copy Image Path", command= lambda name=image_name: self.to_clipboard(name)) 


class DerivedMenu(BaseMenu): 
    def __init__(self, root, ...): 
     super().__init__(root) 
     self.menu.add_command(label="Another command" ...) 

Использование:

menu=BaseMenu(root, imgname) 
menu.post(event) 

или:

menu=DerivedMenu(root, ...) 
menu.post(event) 
0

Затем определите ваши event_handlers который позволит упростить процесс и вызвать метод, который будет переопределено в подклассе песчаники

Например:

class Popup: 
    def __init__ (self, ...): 
     # Set the menu and bind handlers to events (particularly the left click to self.__on_click__()) 

    def __on_click__(self, event): 
     # Something/nothing here 
     self.OnClick(event) 
     # Something/nothing here too 

    # Event handler to be overridden 
    def OnClick (self, event): pass 

    # Or simply call handlers upon events directly if you don't need anything internal to happen. 

Тогда просто переопределить обработчик из подкласса, или вы можете сделать это даже снаружи:

# From outside: 
def ActivateSomething (self, e): 
    if e.GetId()==20: print "Option 1" 
    else: print "Something else" 
popup = Popup() 
popup.OnClick = ActivateSomething 

# Or, of course: 
class MyPopup (Popup): 
    def OnClick (self, e): 
     if e.GetId()==20: print "Option 1" 
     else: print "Something else" 

ПРИМЕЧАНИЕ: Это несколько псевдокод-IC

Обычно я так делаю. Не только для меню, но и для других GUI.

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

Смежные вопросы