Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flexibility of the target function's signature? #14

Open
Guimoute opened this issue Nov 3, 2020 · 0 comments
Open

Flexibility of the target function's signature? #14

Guimoute opened this issue Nov 3, 2020 · 0 comments

Comments

@Guimoute
Copy link

Guimoute commented Nov 3, 2020

Hello,
I just discovered your library and I already find it very very practical. I have a program which can already load files through a pop-up (PyQt5's QFileDialog) and would like to add the option to load them via context menu too.

My question is: can the function's signature be more flexible?
As of now, it seems that only f(filenames, params) and f(filenames=None, params=None) are supported. f(**kwargs) would be very handy as we could still recover the filenames and params while allowing extra parameters, and f(self, ...) would be amazing too for when your target function is actually a method.

I have prepared test cases for you.
The code below will add four context menu actions for files. Only actions 1 and 2 actually work, while 3 and 4 (the kwargs and class variants) don't. Uncomment the code in the context manager and run the code again to remove those context menu actions.

Thank you in advance!

from contextlib import contextmanager

@contextmanager
def add_context_menu_action(action_name, function):
    """Add a context menu action only for the duration of the encompassed scope.

       args:
       -----
       :action_name: (str) the label of the action button.
       :function: the function to call on action button click. Because of the
                  context-menu library requirements, this function must have
                  a `function(filenames, params)` signature. No *args or **kwargs.

       See also:
       -----
       https://github.com/saleguas/context_menu
       https://pypi.org/project/context-menu/"""

    # Creates a direct context menu entry.
    kwargs = dict(name=action_name, type="FILES")
    fc = menus.FastCommand(**kwargs, python=function)
    fc.compile()
#    yield
#    try:
#        menus.removeMenu(**kwargs)
#    except FileNotFoundError: # Prevents an error if the function could not be located.
#        pass



def _TEST1(filenames, params):

    with open("ZE_TEST 1.txt", "w") as file:
        file.write(f"filenames: {filenames}\n")
        file.write(f"params: {params}\n")
        file.write("*"*15)



def _TEST2(filenames=None, params=None):

    with open("ZE_TEST 2.txt", "w") as file:
        file.write(f"filenames: {filenames}\n")
        file.write(f"params: {params}\n")
        file.write("*"*15)



def _TEST3(**kwargs):

    filenames, params = (kwargs[key] for key in ("filenames", "params"))
    with open("ZE_TEST 3.txt", "w") as file:
        file.write(f"filenames: {filenames}\n")
        file.write(f"params: {params}\n")
        file.write("*"*15)



class MethodTester:

    def __init__(self):
        pass

    def _TEST4(self, filenames, params):
        with open("ZE_TEST 4.txt", "w") as file:
            file.write(f"filenames: {filenames}\n")
            file.write(f"params: {params}\n")
            file.write("*"*15)



if __name__ == "__main__":

    x = MethodTester()
    for n in (1, 2, 3, 4):
        name = f"ZE_TEST FastCommand {n}"
        function = {1: _TEST1,
                    2: _TEST2,
                    3: _TEST3,
                    4: x._TEST4}[n]
        with add_context_menu_action(name, function):
            pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant