diff --git a/dwi_ml/GUI/args_management/argparse_equivalent.py b/dwi_ml/GUI/args_management/argparse_equivalent.py index d64327c4..8c862800 100644 --- a/dwi_ml/GUI/args_management/argparse_equivalent.py +++ b/dwi_ml/GUI/args_management/argparse_equivalent.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import logging + store_options = ['store_true', 'store_false'] @@ -35,6 +37,8 @@ def format_arg(argname, help, metavar=None, type=str, default=None, class ArgparserForGui: def __init__(self, description=None): + logging.debug(" GUI.args_management.argparse_equivalent: " + "Initializing ArgparserForGui") self.description = description self.required_args_list = {} self.optional_args_list = {} diff --git a/dwi_ml/GUI/args_management/args_to_gui_all_args.py b/dwi_ml/GUI/args_management/args_to_gui_all_args.py index 4d382ab2..35d90e5f 100644 --- a/dwi_ml/GUI/args_management/args_to_gui_all_args.py +++ b/dwi_ml/GUI/args_management/args_to_gui_all_args.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import logging + import dearpygui.dearpygui as dpg from dwi_ml.GUI.args_management.argparse_equivalent import ArgparserForGui @@ -23,6 +25,8 @@ def add_args_to_gui(gui_parser: ArgparserForGui, known_file_dialogs=None): List of str = accepted extensions (for files only). ex: { 'out_filename': ['unique_file', ['.txt']]} """ + logging.debug(" GUI.args_management.args_to_gui_all_args: adding args " + "to GUI.") my_fonts = get_my_fonts_dictionary() # 1. Required args: diff --git a/dwi_ml/GUI/args_management/args_to_gui_one_arg.py b/dwi_ml/GUI/args_management/args_to_gui_one_arg.py index 33aabedf..21fe78db 100644 --- a/dwi_ml/GUI/args_management/args_to_gui_one_arg.py +++ b/dwi_ml/GUI/args_management/args_to_gui_one_arg.py @@ -13,6 +13,7 @@ | ------------------------------- | |---------------------- ----------------|| ------------------------------------------------------------------------------- """ +import logging from typing import Dict, List import dearpygui.dearpygui as dpg @@ -58,13 +59,6 @@ def add_one_arg_and_help_to_gui( """ known_file_dialogs = known_file_dialogs or {} - # First, fix the params for our usage - # For us, const is the same as default. - if params['nargs'] == '?': - assert params['const'] is not None - assert params['default'] is None - params['default'] = params['const'] - # Verify if optional optional = True if argname[0] == '-' else False @@ -177,38 +171,68 @@ def _get_nb_nargs(params): def check_nargs_add_input(argname, params): - gui_narg_min, gui_narg_max = _get_nb_nargs(params) + logging.debug(" GUI.args_to_gui_one_arg: Checking nargs, adding input") - if gui_narg_max > gui_narg_min: - # Add a button to add more params and another to remove them + narg_min, narg_max = _get_nb_nargs(params) + logging.debug("For arg {}, expecting between {} and {} args." + .format(argname, narg_min, narg_max)) - # Mutable value to keep track of nargs: - current_nb = {'current_nb': gui_narg_min} - user_data = (current_nb, gui_narg_max, argname, params) + if params['nargs'] == '?': + _add_const_input() + else: + if narg_max > narg_min: + _add_more_less_nargs_buttons(argname, narg_min, narg_max, params) + _add_initial_inputs(argname, narg_min, params) - dpg.add_button(label="Add more values", - parent=argname + OPTIONS_CELL, - tag=argname + ADD_NARGS_BUTTON, - callback=__callback_add_new_narg, - user_data=user_data) - # Add a button to remove params, but deactivated for now - # Button only exists if it is possible one day to remove nargs. - dpg.add_button(label="Remove values", - parent=argname + OPTIONS_CELL, - tag=argname + REMOVE_NARGS_BUTTON, - callback=__callback_remove_new_nargs, - user_data=user_data, enabled=False) +def _add_const_input(): + pass - # Add the minimal number of nargs right now. - parent = argname + INPUTS_CELL - with dpg.group(tag=argname + NARGS_GROUP): - for n in range(gui_narg_min): - tag = argname + 'narg{}'.format(n) # tags start at 0 - add_input_item_based_on_type(params, parent, tag) +def _add_more_less_nargs_buttons(argname, narg_min, narg_max, params): + # Add a button to add more params and another to remove them + + # Mutable value to keep track of nargs: + current_nb = {'current_nb': narg_min} + user_data = (current_nb, narg_max, argname, params) -def __callback_add_new_narg(sender, __, user_data): + if not dpg.does_item_exist(argname + OPTIONS_CELL): + raise NotImplementedError("Wrong implementation. Wanted to add " + "the 'add_more_nargs' button, but " + "parent OPTIONS_CELL does not exist.") + logging.debug("ADDING MORE NARGS BUTTON") + dpg.add_button(label="Add more values", + parent=argname + OPTIONS_CELL, + tag=argname + ADD_NARGS_BUTTON, + callback=__callback_add_new_narg, + user_data=user_data) + + # Add a button to remove params, but deactivated for now + # Button only exists if it is possible one day to remove nargs. + logging.debug("ADDING LESS NARGS BUTTON") + dpg.add_button(label="Remove values", + parent=argname + OPTIONS_CELL, + tag=argname + REMOVE_NARGS_BUTTON, + callback=__callback_remove_new_nargs, + user_data=user_data, enabled=False) + + +def _add_initial_inputs(argname, narg_min, params): + # Add the minimal number of nargs right now. + if not dpg.does_item_exist(argname + INPUTS_CELL): + raise NotImplementedError("Wrong implementation. Wanted to add " + "the 'add_more_nargs' button, but " + "parent INPUTS_CELL does not exist.") + logging.debug("ADDING NARGS GROUP") + with dpg.group(tag=argname + NARGS_GROUP, + parent=argname + INPUTS_CELL) as nargs_group: + for n in range(narg_min): + logging.debug("ADDING NARG #{} INPUT".format(n)) + tag = argname + 'narg{}'.format(n) # tags start at 0 + add_input_item_based_on_type(params, parent=nargs_group, tag=tag) + + +def __callback_add_new_narg(_, __, user_data): """ Callback given to the input section when nargs is set (one per narg). @@ -221,6 +245,7 @@ def __callback_add_new_narg(sender, __, user_data): params: dict Argparser params. """ + logging.debug(" GUI.args_to_gui_one_arg: Callback add new arg") current_nb, gui_narg_max, argname, params = user_data nb_nargs = current_nb['current_nb'] # Number of args already added @@ -244,6 +269,7 @@ def __callback_add_new_narg(sender, __, user_data): def __callback_remove_new_nargs(_, __, user_data): + logging.debug(" GUI.args_to_gui_one_arg: Callback remove new arg") arg_info, nmin = user_data arg_name = list(arg_info.keys())[0] nb_nargs = arg_info[arg_name] @@ -266,6 +292,8 @@ def __callback_allow_optional_input(_, app_data, user_data): exclusive_list: list of other args that cannot be modified at the same time. """ + logging.debug(" GUI.args_to_gui_one_arg: Callback set optional arg.") + argname, params, exclusive_list = user_data if app_data: @@ -273,13 +301,16 @@ def __callback_allow_optional_input(_, app_data, user_data): # Remove the "Default = X" text; will replace by input receiver if dpg.does_item_exist(argname + OPTION_DEFAULT_TEXTBOX): + logging.debug("- Hiding 'default=' text") dpg.hide_item(argname + OPTION_DEFAULT_TEXTBOX) if not dpg.does_item_exist(argname + NARGS_GROUP): # If it's the first call, prepare buttons + logging.debug("- Preparing nargs buttons") check_nargs_add_input(argname, params) else: # Else, show group back + nargs buttons + logging.debug("- Showing back nargs buttons") dpg.show_item(argname + NARGS_GROUP) if dpg.does_item_exist(argname + ADD_NARGS_BUTTON): dpg.show_item(argname + ADD_NARGS_BUTTON) @@ -288,26 +319,24 @@ def __callback_allow_optional_input(_, app_data, user_data): # Verifying that other values in the exclusive groups are not also # modified. If so, unselect them. if exclusive_list is not None: + logging.debug("Hiding other exlusive args") for excl_arg in exclusive_list: if excl_arg != argname: dpg.set_value(excl_arg + OPTION_CHECKBOX, False) # Change checkbox text - if params['action'] in store_options: - dpg.set_item_label(argname + OPTION_CHECKBOX, "Unclick to unset") - else: - - dpg.set_item_label(argname + OPTION_CHECKBOX, - "Unclick to use default") + dpg.set_item_label(argname + OPTION_CHECKBOX, "Unclick to unset") else: # Uncliking! (Changed our mind. Not using anymore) # Show back text with "default = " if dpg.does_item_exist(argname + OPTION_DEFAULT_TEXTBOX): + logging.debug("- Showing back 'default=' text.") dpg.show_item(argname + OPTION_DEFAULT_TEXTBOX) # Remove nargs, and possibly buttons + logging.debug("- Hiding nargs buttons") dpg.hide_item(argname + NARGS_GROUP) if dpg.does_item_exist(argname + ADD_NARGS_BUTTON): dpg.hide_item(argname + ADD_NARGS_BUTTON) diff --git a/dwi_ml/GUI/main_menu.py b/dwi_ml/GUI/main_menu.py index f9d19256..5f80f4b3 100644 --- a/dwi_ml/GUI/main_menu.py +++ b/dwi_ml/GUI/main_menu.py @@ -10,7 +10,8 @@ def prepare_main_menu(): - logging.debug("Preparing main window...") + logging.debug("GUI.main_menu.prepare_main_menu(): " + "Preparing main window...") titles = [] with dpg.window(tag="Primary Window"): @@ -45,5 +46,3 @@ def prepare_main_menu(): dpg.bind_item_font(title, my_fonts['section_title']) dpg.set_primary_window("Primary Window", True) - - logging.debug("...main window done.\n") diff --git a/dwi_ml/GUI/menu1_create_hdf5.py b/dwi_ml/GUI/menu1_create_hdf5.py index 78d7bdf2..7965396f 100644 --- a/dwi_ml/GUI/menu1_create_hdf5.py +++ b/dwi_ml/GUI/menu1_create_hdf5.py @@ -16,7 +16,8 @@ def open_menu_create_hdf5(): - logging.debug("Preparing HDF5 window...") + logging.debug("GUI.menu1_create_hdf5.open_menu_create_hdf5(): " + "Preparing HDF5 window...") main_window = dpg.get_active_window() dpg.hide_item(main_window) @@ -38,7 +39,9 @@ def open_menu_create_hdf5(): " " " CREATE A HDF5 DATASET:\n\n") dpg.add_text("Choose your options. We will prepare a bash script " - "using dwiml_create_hdf5_dataset.py") + "using dwiml_create_hdf5_dataset.py\n" + "***************************************************" + "***************************************************") # Creating known file dialogs. # If arg names in the script change and if we don't make the @@ -72,18 +75,17 @@ def open_menu_create_hdf5(): dpg.add_text("\n") dpg.add_button( label='OK! Create my script!', indent=1005, width=200, - height=100, callback=_create_hdf5_script, + height=100, callback=__create_hdf5_script_callback, user_data=gui_parser) # Set Title fonts my_fonts = get_my_fonts_dictionary() dpg.bind_item_font(main_title, my_fonts['main_title']) - logging.debug("...HDF5 window done.\n") - -def _create_hdf5_script(_, __, user_data): - logging.debug("Getting all user choices and preparing HDF5 bash script.") +def __create_hdf5_script_callback(_, __, user_data): + logging.debug("GUI.menu1_create_hdf5.__create_hdf5_script_callback(): " + "Preparing script...") # 1. Verify that user defined where to save the script. out_path = dpg.get_value(TAG_HDF_SCRIPT_PATH) diff --git a/dwi_ml/GUI/menu1_l2t.py b/dwi_ml/GUI/menu1_l2t.py index af5dabcb..b9a5fc64 100644 --- a/dwi_ml/GUI/menu1_l2t.py +++ b/dwi_ml/GUI/menu1_l2t.py @@ -12,7 +12,8 @@ def open_menu_learn2track(): - logging.debug("Preparing L2T window...") + logging.debug("GUI.menu1_l2t.open_menu_learn2track(): " + "Preparing L2T window...") main_window = dpg.get_active_window() dpg.hide_item(main_window) diff --git a/dwi_ml/GUI/menu1_tt.py b/dwi_ml/GUI/menu1_tt.py index 0ea9435e..995c7811 100644 --- a/dwi_ml/GUI/menu1_tt.py +++ b/dwi_ml/GUI/menu1_tt.py @@ -11,7 +11,8 @@ def open_menu_transformers(): - logging.debug("Preparing TT window...") + logging.debug("GUI.menu1_tt.open_menu_transformers(): " + "Preparing TT window...") main_window = dpg.get_active_window() dpg.hide_item(main_window) diff --git a/scripts_python/dwiml_launch_GUI.py b/scripts_python/dwiml_launch_GUI.py index d1e8e6d6..a5c9e2e8 100644 --- a/scripts_python/dwiml_launch_GUI.py +++ b/scripts_python/dwiml_launch_GUI.py @@ -1,13 +1,28 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +""" +Launch the GUI to help you prepare a script with all your favorite options. +""" +import argparse import logging from dwi_ml.GUI.main_menu import prepare_main_menu from dwi_ml.GUI.utils.window import start_dpg, show_and_end_dpg +from dwi_ml.io_utils import add_logging_arg + + +def _prepare_argparser(): + p = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawTextHelpFormatter) + add_logging_arg(p) + return p def main(): - logging.getLogger().setLevel(level='DEBUG') + p = _prepare_argparser() + args = p.parse_args() + logging.getLogger().setLevel(args.logging) + start_dpg() prepare_main_menu()