ezinput.ezinput_jupyter
1import os 2import yaml 3from ipyfilechooser import FileChooser 4import ipywidgets as widgets 5from IPython.display import display, clear_output 6from pathlib import Path 7 8from typing import Optional 9 10""" 11A module to help simplify the create of GUIs in Jupyter notebooks using ipywidgets. 12""" 13 14CONFIG_PATH = Path.home() / ".ezinput" 15 16if not os.path.exists(CONFIG_PATH): 17 os.makedirs(CONFIG_PATH) 18 19 20class EZInputJupyter: 21 """ 22 A class to create GUIs in Jupyter notebooks using `ipywidgets`. 23 24 Parameters 25 ---------- 26 title : str, optional 27 Title of the GUI, used to store settings. Defaults to "basic_gui". 28 width : str, optional 29 Width of the widget container. Defaults to "50%". 30 """ 31 32 def __init__(self, title="basic_gui", width="50%"): 33 """ 34 Container for widgets. 35 36 Parameters 37 ---------- 38 title : str, optional 39 The title of the widget container, used to store settings. 40 width : str, optional 41 The width of the widget container. 42 """ 43 pass 44 45 def __getvalue__(self, tag: str): 46 """ 47 @unified 48 Get the value of a widget. 49 50 Parameters 51 ---------- 52 tag : str 53 Tag to identify the widget. 54 55 Returns 56 ------- 57 Any 58 The value of the widget. 59 """ 60 return self.elements[tag].value 61 62 def __getitem__(self, tag: str) -> widgets.Widget: 63 """ 64 Get a widget by tag. 65 66 Parameters 67 ---------- 68 tag : str 69 The tag of the widget. 70 71 Returns 72 ------- 73 widgets.Widget 74 The widget. 75 """ 76 return self.elements[tag] 77 78 def __len__(self) -> int: 79 """ 80 Get the number of widgets. 81 82 Returns 83 ------- 84 int 85 The number of widgets. 86 """ 87 return len(self.elements) 88 89 def add_label(self, value="", *args, **kwargs): 90 """ 91 @unified 92 Add a label widget to the container. 93 94 Parameters 95 ---------- 96 label : str, optional 97 The label text to display. Defaults to "". 98 *args : tuple 99 Additional positional arguments for the widget. 100 **kwargs : dict 101 Additional keyword arguments for the widget. 102 """ 103 self._nLabels += 1 104 style = kwargs.pop("style", self._style) 105 self.elements[f"label_{self._nLabels}"] = widgets.Label( 106 value=value, 107 *args, 108 **kwargs, 109 layout=self._layout, 110 style=style, 111 ) 112 113 def add_text( 114 self, 115 tag: str, 116 description: str = "", 117 placeholder: str = "", 118 *args, 119 remember_value=False, 120 **kwargs, 121 ): 122 """ 123 @unified 124 Add a text widget to the container. 125 126 Parameters 127 ---------- 128 tag : str 129 Tag to identify the widget. 130 description : str, optional 131 The message to display. Defaults to "". 132 placeholder : str, optional 133 Placeholder text for the input field. Defaults to "". 134 remember_value : bool, optional 135 Whether to remember the last entered value. Defaults to False. 136 *args : tuple 137 Additional positional arguments for the widget. 138 **kwargs : dict 139 Additional keyword arguments for the widget. 140 """ 141 if self.params is not None: 142 if tag in self.params: 143 kwargs["value"] = self.params[tag] 144 elif remember_value and tag in self.cfg: 145 kwargs["value"] = str(self.cfg[tag]) 146 147 style = kwargs.pop("style", self._style) 148 self.elements[tag] = widgets.Text( 149 description=description, 150 placeholder=placeholder, 151 *args, 152 **kwargs, 153 layout=self._layout, 154 style=style, 155 ) 156 157 def add_callback( 158 self, tag, func, values: dict, description="Run", *args, **kwargs 159 ): 160 """ 161 @unified 162 Add a button widget to the container. 163 164 Parameters 165 ---------- 166 tag : str 167 Tag to identify the widget. 168 func : callable 169 The function to call when the button is clicked. 170 values : dict 171 Dictionary of widget values to pass to the callback function. 172 description : str, optional 173 The label for the button. Defaults to "Run". 174 *args : tuple 175 Additional positional arguments for the button. 176 **kwargs : dict 177 Additional keyword arguments for the button. 178 """ 179 style = kwargs.pop("style", self._style) 180 self.elements[tag] = widgets.Button( 181 description=description, 182 *args, 183 **kwargs, 184 layout=self._layout, 185 style=style, 186 ) 187 188 def wrapped(button): 189 self.save_settings() 190 func(values) 191 192 self.elements[tag].on_click(wrapped) 193 194 def add_button(self, tag, description="Run", *args, **kwargs): 195 """ 196 @jupyter 197 Add a button widget to the container. 198 199 Parameters 200 ---------- 201 tag : str 202 Tag to identify the widget. 203 description : str, optional 204 The label for the button. Defaults to "Run". 205 *args : tuple 206 Additional positional arguments for the widget. 207 **kwargs : dict 208 Additional keyword arguments for the widget. 209 """ 210 style = kwargs.pop("style", self._style) 211 self.elements[tag] = widgets.Button( 212 description=description, 213 *args, 214 **kwargs, 215 layout=self._layout, 216 style=style, 217 ) 218 219 def add_text_area( 220 self, 221 tag: str, 222 description: str = "", 223 placeholder: str = "", 224 *args, 225 remember_value=False, 226 on_change: Optional[callable] = None, 227 **kwargs, 228 ): 229 """ 230 @unified 231 Add a textarea widget to the container. 232 233 Parameters 234 ---------- 235 tag : str 236 Tag to identify the widget. 237 description : str, optional 238 The message to display. Defaults to "". 239 placeholder : str, optional 240 Placeholder text for the input field. Defaults to "". 241 remember_value : bool, optional 242 Whether to remember the last entered value. Defaults to False. 243 *args : tuple 244 Additional positional arguments for the widget. 245 **kwargs : dict 246 Additional keyword arguments for the widget. 247 """ 248 if self.params is not None: 249 if tag in self.params: 250 kwargs["value"] = self.params[tag] 251 elif remember_value and tag in self.cfg: 252 kwargs["value"] = str(self.cfg[tag]) 253 style = kwargs.pop("style", self._style) 254 self.elements[tag] = widgets.Textarea( 255 description=description, 256 placeholder=placeholder, 257 *args, 258 **kwargs, 259 layout=self._layout, 260 style=style, 261 ) 262 263 if on_change is not None: 264 self.elements[tag].observe(on_change, names="value") 265 266 def add_HTML( 267 self, tag: str, value: str, description: str = "", *args, **kwargs 268 ): 269 """ 270 @jupyter 271 Add an HTML widget to the container. 272 273 Parameters 274 ---------- 275 tag : str 276 Tag to identify the widget. 277 value : str 278 The HTML content to display. 279 *args : tuple 280 Additional positional arguments for the widget. 281 **kwargs : dict 282 Additional keyword arguments for the widget. 283 """ 284 style = kwargs.pop("style", self._style) 285 self.elements[tag] = widgets.HTML( 286 value=value, 287 description=description, 288 *args, 289 **kwargs, 290 layout=self._layout, 291 style=style, 292 ) 293 294 def add_int_range( 295 self, 296 tag: str, 297 description: str, 298 vmin: int, 299 vmax: int, 300 *args, 301 remember_value=False, 302 on_change: Optional[callable] = None, 303 **kwargs, 304 ): 305 """ 306 @unified 307 Add an integer slider widget to the container. 308 309 Parameters 310 ---------- 311 tag : str 312 Tag to identify the widget. 313 description : str 314 The message to display. 315 vmin : int 316 Minimum value of the slider. 317 vmax : int 318 Maximum value of the slider. 319 remember_value : bool, optional 320 Whether to remember the last selected value. Defaults to False. 321 *args : tuple 322 Additional positional arguments for the widget. 323 **kwargs : dict 324 Additional keyword arguments for the widget. 325 """ 326 if self.params is not None: 327 if tag in self.params and vmin <= self.params[tag] <= vmax: 328 kwargs["value"] = self.params[tag] 329 elif ( 330 remember_value 331 and tag in self.cfg 332 and vmin <= self.cfg[tag] <= vmax 333 ): 334 kwargs["value"] = int(self.cfg[tag]) 335 style = kwargs.pop("style", self._style) 336 self.elements[tag] = widgets.IntSlider( 337 description=description, 338 min=vmin, 339 max=vmax, 340 *args, 341 **kwargs, 342 layout=self._layout, 343 style=style, 344 ) 345 346 if on_change is not None: 347 self.elements[tag].observe(on_change, names="value") 348 349 def add_int_slider( 350 self, 351 tag: str, 352 description: str, 353 min: int, 354 max: int, 355 *args, 356 remember_value=False, 357 on_change: Optional[callable] = None, 358 **kwargs, 359 ): 360 """ 361 @jupyter 362 Add an integer slider widget to the container. 363 364 Parameters 365 ---------- 366 tag : str 367 Tag to identify the widget. 368 description : str 369 The message to display. 370 vmin : int 371 Minimum value of the slider. 372 vmax : int 373 Maximum value of the slider. 374 remember_value : bool, optional 375 Whether to remember the last selected value. Defaults to False. 376 *args : tuple 377 Additional positional arguments for the widget. 378 **kwargs : dict 379 Additional keyword arguments for the widget. 380 """ 381 self.add_int_range( 382 tag, 383 description, 384 vmin=min, 385 vmax=max, 386 *args, 387 remember_value=remember_value, 388 **kwargs, 389 ) 390 391 if on_change is not None: 392 self.elements[tag].observe(on_change, names="value") 393 394 def add_float_range( 395 self, 396 tag: str, 397 description: str, 398 vmin: float, 399 vmax: float, 400 *args, 401 remember_value=False, 402 on_change: Optional[callable] = None, 403 **kwargs, 404 ): 405 """ 406 @unified 407 Add a float slider widget to the container. 408 409 Parameters 410 ---------- 411 tag : str 412 Tag to identify the widget. 413 description : str 414 The message to display. 415 vmin : float 416 Minimum value of the slider. 417 vmax : float 418 Maximum value of the slider. 419 remember_value : bool, optional 420 Whether to remember the last selected value. Defaults to False. 421 *args : tuple 422 Additional positional arguments for the widget. 423 **kwargs : dict 424 Additional keyword arguments for the widget. 425 """ 426 if self.params is not None: 427 if tag in self.params and vmin <= self.params[tag] <= vmax: 428 kwargs["value"] = self.params[tag] 429 elif ( 430 remember_value 431 and tag in self.cfg 432 and vmin <= self.cfg[tag] <= vmax 433 ): 434 kwargs["value"] = int(self.cfg[tag]) 435 style = kwargs.pop("style", self._style) 436 self.elements[tag] = widgets.FloatSlider( 437 description=description, 438 min=vmin, 439 max=vmax, 440 *args, 441 **kwargs, 442 layout=self._layout, 443 style=style, 444 ) 445 446 if on_change is not None: 447 self.elements[tag].observe(on_change, names="value") 448 449 def add_float_slider( 450 self, 451 tag: str, 452 description: str, 453 min: int, 454 max: int, 455 *args, 456 remember_value=False, 457 on_change: Optional[callable] = None, 458 **kwargs, 459 ): 460 """ 461 @jupyter 462 Add an float slider widget to the container. 463 464 Parameters 465 ---------- 466 tag : str 467 Tag to identify the widget. 468 description : str 469 The message to display. 470 min : float 471 Minimum value of the slider. 472 max : float 473 Maximum value of the slider. 474 remember_value : bool, optional 475 Whether to remember the last selected value. Defaults to False. 476 *args : tuple 477 Additional positional arguments for the widget. 478 **kwargs : dict 479 Additional keyword arguments for the widget. 480 """ 481 self.add_float_range( 482 tag, 483 description, 484 vmin=min, 485 vmax=max, 486 *args, 487 remember_value=remember_value, 488 **kwargs, 489 ) 490 491 if on_change is not None: 492 self.elements[tag].observe(on_change, names="value") 493 494 def add_check( 495 self, 496 tag: str, 497 description: str, 498 *args, 499 remember_value=False, 500 on_change: Optional[callable] = None, 501 **kwargs, 502 ): 503 """ 504 @unified 505 Add a checkbox widget to the container. 506 507 Parameters 508 ---------- 509 tag : str 510 Tag to identify the widget. 511 description : str 512 The message to display. 513 remember_value : bool, optional 514 Whether to remember the last selected value. Defaults to False. 515 *args : tuple 516 Additional positional arguments for the widget. 517 **kwargs : dict 518 Additional keyword arguments for the widget. 519 """ 520 if self.params is not None: 521 if tag in self.params: 522 kwargs["value"] = self.params[tag] 523 elif remember_value and tag in self.cfg: 524 kwargs["value"] = self.cfg[tag] 525 style = kwargs.pop("style", self._style) 526 self.elements[tag] = widgets.Checkbox( 527 description=description, 528 *args, 529 **kwargs, 530 layout=self._layout, 531 style=style, 532 ) 533 534 if on_change is not None: 535 self.elements[tag].observe(on_change, names="value") 536 537 def add_int_text( 538 self, 539 tag, 540 description: str = "", 541 *args, 542 remember_value=False, 543 on_change: Optional[callable] = None, 544 **kwargs, 545 ): 546 """ 547 @unified 548 Add an integer text widget to the container. 549 550 Parameters 551 ---------- 552 tag : str 553 Tag to identify the widget. 554 description : str, optional 555 The message to display. Defaults to "". 556 remember_value : bool, optional 557 Whether to remember the last entered value. Defaults to False. 558 *args : tuple 559 Additional positional arguments for the widget. 560 **kwargs : dict 561 Additional keyword arguments for the widget. 562 """ 563 if self.params is not None: 564 if tag in self.params: 565 kwargs["value"] = self.params[tag] 566 elif remember_value and tag in self.cfg: 567 kwargs["value"] = self.cfg[tag] 568 569 style = kwargs.pop("style", self._style) 570 self.elements[tag] = widgets.IntText( 571 description=description, 572 *args, 573 **kwargs, 574 layout=self._layout, 575 style=style, 576 ) 577 578 if on_change is not None: 579 self.elements[tag].observe(on_change, names="value") 580 581 def add_bounded_int_text( 582 self, 583 tag, 584 description: str, 585 vmin: int, 586 vmax: int, 587 *args, 588 remember_value=False, 589 on_change: Optional[callable] = None, 590 **kwargs, 591 ): 592 """ 593 @unified 594 Add a bounded integer text widget to the container. 595 596 Parameters 597 ---------- 598 tag : str 599 Tag to identify the widget. 600 description : str 601 The message to display. 602 vmin : int 603 Minimum value of the input field. 604 vmax : int 605 Maximum value of the input field. 606 remember_value : bool, optional 607 Whether to remember the last entered value. Defaults to False. 608 *args : tuple 609 Additional positional arguments for the widget. 610 **kwargs : dict 611 Additional keyword arguments for the widget. 612 """ 613 if self.params is not None: 614 if tag in self.params: 615 kwargs["value"] = self.params[tag] 616 elif remember_value and tag in self.cfg: 617 kwargs["value"] = self.cfg[tag] 618 style = kwargs.pop("style", self._style) 619 self.elements[tag] = widgets.BoundedIntText( 620 min=vmin, 621 max=vmax, 622 description=description, 623 *args, 624 **kwargs, 625 layout=self._layout, 626 style=style, 627 ) 628 629 if on_change is not None: 630 self.elements[tag].observe(on_change, names="value") 631 632 def add_float_text( 633 self, 634 tag, 635 description: str = "", 636 *args, 637 remember_value=False, 638 on_change: Optional[callable] = None, 639 **kwargs, 640 ): 641 """ 642 @unified 643 Add a float text widget to the container. 644 645 Parameters 646 ---------- 647 tag : str 648 Tag to identify the widget. 649 description : str, optional 650 The message to display. Defaults to "". 651 remember_value : bool, optional 652 Whether to remember the last entered value. Defaults to False. 653 *args : tuple 654 Additional positional arguments for the widget. 655 **kwargs : dict 656 Additional keyword arguments for the widget. 657 """ 658 if self.params is not None: 659 if tag in self.params: 660 kwargs["value"] = self.params[tag] 661 elif remember_value and tag in self.cfg: 662 kwargs["value"] = self.cfg[tag] 663 style = kwargs.pop("style", self._style) 664 self.elements[tag] = widgets.FloatText( 665 description=description, 666 *args, 667 **kwargs, 668 layout=self._layout, 669 style=style, 670 ) 671 672 if on_change is not None: 673 self.elements[tag].observe(on_change, names="value") 674 675 def add_bounded_float_text( 676 self, 677 tag, 678 description: str, 679 vmin: int, 680 vmax: int, 681 *args, 682 remember_value=False, 683 on_change: Optional[callable] = None, 684 **kwargs, 685 ): 686 """ 687 @unified 688 Add a bounded float text widget to the container. 689 690 Parameters 691 ---------- 692 tag : str 693 Tag to identify the widget. 694 description : str 695 The message to display. 696 vmin : int 697 Minimum value of the input field. 698 vmax : int 699 Maximum value of the input field. 700 remember_value : bool, optional 701 Whether to remember the last entered value. Defaults to False. 702 *args : tuple 703 Additional positional arguments for the widget. 704 **kwargs : dict 705 Additional keyword arguments for the widget. 706 """ 707 if self.params is not None: 708 if tag in self.params: 709 kwargs["value"] = self.params[tag] 710 elif remember_value and tag in self.cfg: 711 kwargs["value"] = self.cfg[tag] 712 style = kwargs.pop("style", self._style) 713 self.elements[tag] = widgets.BoundedFloatText( 714 min=vmin, 715 max=vmax, 716 description=description, 717 *args, 718 **kwargs, 719 layout=self._layout, 720 style=style, 721 ) 722 723 if on_change is not None: 724 self.elements[tag].observe(on_change, names="value") 725 726 def add_dropdown( 727 self, 728 tag, 729 options: list, 730 description: str = "", 731 *args, 732 remember_value=False, 733 on_change: Optional[callable] = None, 734 **kwargs, 735 ): 736 """ 737 @unified 738 Add a dropdown widget to the container. 739 740 Parameters 741 ---------- 742 tag : str 743 Tag to identify the widget. 744 options : list 745 List of choices for the dropdown. 746 description : str, optional 747 The message to display. Defaults to "". 748 remember_value : bool, optional 749 Whether to remember the last selected value. Defaults to False. 750 *args : tuple 751 Additional positional arguments for the widget. 752 **kwargs : dict 753 Additional keyword arguments for the widget. 754 """ 755 if remember_value and tag in self.cfg and self.cfg[tag] in options: 756 kwargs["value"] = self.cfg[tag] 757 if self.params is not None: 758 if tag in self.params: 759 kwargs["value"] = self.params[tag] 760 style = kwargs.pop("style", self._style) 761 self.elements[tag] = widgets.Dropdown( 762 options=options, 763 description=description, 764 *args, 765 **kwargs, 766 layout=self._layout, 767 style=style, 768 ) 769 770 if on_change is not None: 771 self.elements[tag].observe(on_change, names="value") 772 773 def add_checkbox( 774 self, 775 tag: str, 776 description: str, 777 *args, 778 remember_value=False, 779 on_change: Optional[callable] = None, 780 **kwargs, 781 ): 782 """ 783 @jupyter 784 Add a checkbox widget to the container. 785 786 Parameters 787 ---------- 788 tag : str 789 Tag to identify the widget. 790 description : str 791 The message to display. 792 remember_value : bool, optional 793 Whether to remember the last selected value. Defaults to False. 794 *args : tuple 795 Additional positional arguments for the widget. 796 **kwargs : dict 797 Additional keyword arguments for the widget. 798 """ 799 self.add_check( 800 tag, 801 description=description, 802 remember_value=remember_value, 803 *args, 804 **kwargs, 805 ) 806 807 if on_change is not None: 808 self.elements[tag].observe(on_change, names="value") 809 810 def add_select_multiple( 811 self, tag: str, options: list, description: str = "", *args, **kwargs 812 ): 813 """ 814 @jupyter 815 Add a multiple selection widget to the container. 816 817 Parameters 818 ---------- 819 tag : str 820 Tag to identify the widget. 821 options : list 822 List of choices for the selection. 823 *args : tuple 824 Additional positional arguments for the widget. 825 **kwargs : dict 826 Additional keyword arguments for the widget. 827 """ 828 style = kwargs.pop("style", self._style) 829 self.elements[tag] = widgets.SelectMultiple( 830 options=options, 831 description=description, 832 *args, 833 **kwargs, 834 layout=self._layout, 835 style=style, 836 ) 837 838 def add_file_upload( 839 self, tag, *args, accept=None, multiple=False, **kwargs 840 ): 841 """ 842 @jupyter 843 Add a file upload widget to the container. 844 845 Parameters 846 ---------- 847 tag : str 848 Tag to identify the widget. 849 accept : str, optional 850 The file types to accept. Defaults to None. 851 multiple : bool, optional 852 Allow multiple files to be uploaded. Defaults to False. 853 *args : tuple 854 Additional positional arguments for the widget. 855 **kwargs : dict 856 Additional keyword arguments for the widget. 857 """ 858 self.elements[tag] = FileChooser() 859 if accept is not None: 860 self.elements[tag].filter_pattern = accept 861 862 def add_output(self, tag: str, *args, **kwargs): 863 """ 864 @unified 865 Add an output widget to the container. 866 867 Parameters 868 ---------- 869 tag : str 870 Tag to identify the widget. 871 *args : tuple 872 Additional positional arguments for the widget. 873 **kwargs : dict 874 Additional keyword arguments for the widget. 875 """ 876 style = kwargs.pop("style", self._style) 877 self.elements[tag] = widgets.Output( 878 *args, 879 **kwargs, 880 layout=self._layout, 881 style=style, 882 ) 883 884 def add_custom_widget( 885 self, 886 tag: str, 887 custom_widget, 888 *args, 889 remember_value=False, 890 on_change: Optional[callable] = None, 891 **kwargs, 892 ): 893 """ 894 @jupyter 895 Add a custom widget to the container. 896 Parameters 897 ---------- 898 tag : str 899 Tag to identify the widget. 900 custom_widget : ipywidget to add 901 The custom widget to add. 902 *args : tuple 903 Additional positional arguments for the widget. 904 **kwargs : dict 905 Additional keyword arguments for the widget. 906 """ 907 if self.params is not None: 908 if tag in self.params: 909 kwargs["value"] = self.params[tag] 910 elif remember_value and tag in self.cfg: 911 kwargs["value"] = self.cfg[tag] 912 style = kwargs.pop("style", self._style) 913 self.elements[tag] = custom_widget( 914 *args, 915 **kwargs, 916 layout=self._layout, 917 style=style, 918 ) 919 920 if on_change is not None: 921 self.elements[tag].observe(on_change, names="value") 922 923 def save_parameters(self, path: str): 924 """ 925 @unified 926 Save the widget values to a file. 927 928 Parameters 929 ---------- 930 path : str 931 The path to save the file. 932 """ 933 if not path.endswith(".yml"): 934 path += f"{self.title}_parameters.yml" 935 out = {} 936 for tag in self.elements: 937 if tag.startswith("label_"): 938 pass 939 elif hasattr(self.elements[tag], "value"): 940 out[tag] = self.elements[tag].value 941 with open(path, "w") as f: 942 yaml.dump(out, f) 943 944 def save_settings(self): 945 """ 946 @unified 947 Save the widget values to the configuration file. 948 """ 949 for tag in self.elements: 950 if tag.startswith("label_"): 951 pass 952 elif hasattr(self.elements[tag], "value"): 953 if type(self.elements[tag].value) != tuple: 954 self.cfg[tag] = self.elements[tag].value 955 config_file = CONFIG_PATH / f"{self.title}.yml" 956 config_file.parent.mkdir(exist_ok=True) 957 958 base_config = self._get_config(self.title) # loads the config file 959 for key, value in self.cfg.items(): 960 base_config[key] = value 961 962 with open(config_file, "w") as f: 963 yaml.dump(base_config, f) 964 965 def show(self): 966 """ 967 @unified 968 Display the widgets in the container. 969 """ 970 self._main_display.children = tuple(self.elements.values()) 971 clear_output() 972 display(self._main_display) 973 974 def clear_elements(self): 975 """ 976 @unified 977 Clear all widgets from the container. 978 """ 979 self.elements = {} 980 self._nLabels = 0 981 self._main_display.children = () 982 983 def _get_config(self, title: Optional[str]) -> dict: 984 """ 985 Get the configuration dictionary without needing to initialize the GUI. 986 987 Parameters 988 ---------- 989 title : str, optional 990 The title of the GUI. If None, returns the entire configuration. 991 992 Returns 993 ------- 994 dict 995 The configuration dictionary. 996 """ 997 998 config_file = CONFIG_PATH / f"{title}.yml" 999 1000 if not config_file.exists(): 1001 return {} 1002 1003 with open(config_file, "r") as f: 1004 return yaml.load(f, Loader=yaml.SafeLoader)
21class EZInputJupyter: 22 """ 23 A class to create GUIs in Jupyter notebooks using `ipywidgets`. 24 25 Parameters 26 ---------- 27 title : str, optional 28 Title of the GUI, used to store settings. Defaults to "basic_gui". 29 width : str, optional 30 Width of the widget container. Defaults to "50%". 31 """ 32 33 def __init__(self, title="basic_gui", width="50%"): 34 """ 35 Container for widgets. 36 37 Parameters 38 ---------- 39 title : str, optional 40 The title of the widget container, used to store settings. 41 width : str, optional 42 The width of the widget container. 43 """ 44 pass 45 46 def __getvalue__(self, tag: str): 47 """ 48 @unified 49 Get the value of a widget. 50 51 Parameters 52 ---------- 53 tag : str 54 Tag to identify the widget. 55 56 Returns 57 ------- 58 Any 59 The value of the widget. 60 """ 61 return self.elements[tag].value 62 63 def __getitem__(self, tag: str) -> widgets.Widget: 64 """ 65 Get a widget by tag. 66 67 Parameters 68 ---------- 69 tag : str 70 The tag of the widget. 71 72 Returns 73 ------- 74 widgets.Widget 75 The widget. 76 """ 77 return self.elements[tag] 78 79 def __len__(self) -> int: 80 """ 81 Get the number of widgets. 82 83 Returns 84 ------- 85 int 86 The number of widgets. 87 """ 88 return len(self.elements) 89 90 def add_label(self, value="", *args, **kwargs): 91 """ 92 @unified 93 Add a label widget to the container. 94 95 Parameters 96 ---------- 97 label : str, optional 98 The label text to display. Defaults to "". 99 *args : tuple 100 Additional positional arguments for the widget. 101 **kwargs : dict 102 Additional keyword arguments for the widget. 103 """ 104 self._nLabels += 1 105 style = kwargs.pop("style", self._style) 106 self.elements[f"label_{self._nLabels}"] = widgets.Label( 107 value=value, 108 *args, 109 **kwargs, 110 layout=self._layout, 111 style=style, 112 ) 113 114 def add_text( 115 self, 116 tag: str, 117 description: str = "", 118 placeholder: str = "", 119 *args, 120 remember_value=False, 121 **kwargs, 122 ): 123 """ 124 @unified 125 Add a text widget to the container. 126 127 Parameters 128 ---------- 129 tag : str 130 Tag to identify the widget. 131 description : str, optional 132 The message to display. Defaults to "". 133 placeholder : str, optional 134 Placeholder text for the input field. Defaults to "". 135 remember_value : bool, optional 136 Whether to remember the last entered value. Defaults to False. 137 *args : tuple 138 Additional positional arguments for the widget. 139 **kwargs : dict 140 Additional keyword arguments for the widget. 141 """ 142 if self.params is not None: 143 if tag in self.params: 144 kwargs["value"] = self.params[tag] 145 elif remember_value and tag in self.cfg: 146 kwargs["value"] = str(self.cfg[tag]) 147 148 style = kwargs.pop("style", self._style) 149 self.elements[tag] = widgets.Text( 150 description=description, 151 placeholder=placeholder, 152 *args, 153 **kwargs, 154 layout=self._layout, 155 style=style, 156 ) 157 158 def add_callback( 159 self, tag, func, values: dict, description="Run", *args, **kwargs 160 ): 161 """ 162 @unified 163 Add a button widget to the container. 164 165 Parameters 166 ---------- 167 tag : str 168 Tag to identify the widget. 169 func : callable 170 The function to call when the button is clicked. 171 values : dict 172 Dictionary of widget values to pass to the callback function. 173 description : str, optional 174 The label for the button. Defaults to "Run". 175 *args : tuple 176 Additional positional arguments for the button. 177 **kwargs : dict 178 Additional keyword arguments for the button. 179 """ 180 style = kwargs.pop("style", self._style) 181 self.elements[tag] = widgets.Button( 182 description=description, 183 *args, 184 **kwargs, 185 layout=self._layout, 186 style=style, 187 ) 188 189 def wrapped(button): 190 self.save_settings() 191 func(values) 192 193 self.elements[tag].on_click(wrapped) 194 195 def add_button(self, tag, description="Run", *args, **kwargs): 196 """ 197 @jupyter 198 Add a button widget to the container. 199 200 Parameters 201 ---------- 202 tag : str 203 Tag to identify the widget. 204 description : str, optional 205 The label for the button. Defaults to "Run". 206 *args : tuple 207 Additional positional arguments for the widget. 208 **kwargs : dict 209 Additional keyword arguments for the widget. 210 """ 211 style = kwargs.pop("style", self._style) 212 self.elements[tag] = widgets.Button( 213 description=description, 214 *args, 215 **kwargs, 216 layout=self._layout, 217 style=style, 218 ) 219 220 def add_text_area( 221 self, 222 tag: str, 223 description: str = "", 224 placeholder: str = "", 225 *args, 226 remember_value=False, 227 on_change: Optional[callable] = None, 228 **kwargs, 229 ): 230 """ 231 @unified 232 Add a textarea widget to the container. 233 234 Parameters 235 ---------- 236 tag : str 237 Tag to identify the widget. 238 description : str, optional 239 The message to display. Defaults to "". 240 placeholder : str, optional 241 Placeholder text for the input field. Defaults to "". 242 remember_value : bool, optional 243 Whether to remember the last entered value. Defaults to False. 244 *args : tuple 245 Additional positional arguments for the widget. 246 **kwargs : dict 247 Additional keyword arguments for the widget. 248 """ 249 if self.params is not None: 250 if tag in self.params: 251 kwargs["value"] = self.params[tag] 252 elif remember_value and tag in self.cfg: 253 kwargs["value"] = str(self.cfg[tag]) 254 style = kwargs.pop("style", self._style) 255 self.elements[tag] = widgets.Textarea( 256 description=description, 257 placeholder=placeholder, 258 *args, 259 **kwargs, 260 layout=self._layout, 261 style=style, 262 ) 263 264 if on_change is not None: 265 self.elements[tag].observe(on_change, names="value") 266 267 def add_HTML( 268 self, tag: str, value: str, description: str = "", *args, **kwargs 269 ): 270 """ 271 @jupyter 272 Add an HTML widget to the container. 273 274 Parameters 275 ---------- 276 tag : str 277 Tag to identify the widget. 278 value : str 279 The HTML content to display. 280 *args : tuple 281 Additional positional arguments for the widget. 282 **kwargs : dict 283 Additional keyword arguments for the widget. 284 """ 285 style = kwargs.pop("style", self._style) 286 self.elements[tag] = widgets.HTML( 287 value=value, 288 description=description, 289 *args, 290 **kwargs, 291 layout=self._layout, 292 style=style, 293 ) 294 295 def add_int_range( 296 self, 297 tag: str, 298 description: str, 299 vmin: int, 300 vmax: int, 301 *args, 302 remember_value=False, 303 on_change: Optional[callable] = None, 304 **kwargs, 305 ): 306 """ 307 @unified 308 Add an integer slider widget to the container. 309 310 Parameters 311 ---------- 312 tag : str 313 Tag to identify the widget. 314 description : str 315 The message to display. 316 vmin : int 317 Minimum value of the slider. 318 vmax : int 319 Maximum value of the slider. 320 remember_value : bool, optional 321 Whether to remember the last selected value. Defaults to False. 322 *args : tuple 323 Additional positional arguments for the widget. 324 **kwargs : dict 325 Additional keyword arguments for the widget. 326 """ 327 if self.params is not None: 328 if tag in self.params and vmin <= self.params[tag] <= vmax: 329 kwargs["value"] = self.params[tag] 330 elif ( 331 remember_value 332 and tag in self.cfg 333 and vmin <= self.cfg[tag] <= vmax 334 ): 335 kwargs["value"] = int(self.cfg[tag]) 336 style = kwargs.pop("style", self._style) 337 self.elements[tag] = widgets.IntSlider( 338 description=description, 339 min=vmin, 340 max=vmax, 341 *args, 342 **kwargs, 343 layout=self._layout, 344 style=style, 345 ) 346 347 if on_change is not None: 348 self.elements[tag].observe(on_change, names="value") 349 350 def add_int_slider( 351 self, 352 tag: str, 353 description: str, 354 min: int, 355 max: int, 356 *args, 357 remember_value=False, 358 on_change: Optional[callable] = None, 359 **kwargs, 360 ): 361 """ 362 @jupyter 363 Add an integer slider widget to the container. 364 365 Parameters 366 ---------- 367 tag : str 368 Tag to identify the widget. 369 description : str 370 The message to display. 371 vmin : int 372 Minimum value of the slider. 373 vmax : int 374 Maximum value of the slider. 375 remember_value : bool, optional 376 Whether to remember the last selected value. Defaults to False. 377 *args : tuple 378 Additional positional arguments for the widget. 379 **kwargs : dict 380 Additional keyword arguments for the widget. 381 """ 382 self.add_int_range( 383 tag, 384 description, 385 vmin=min, 386 vmax=max, 387 *args, 388 remember_value=remember_value, 389 **kwargs, 390 ) 391 392 if on_change is not None: 393 self.elements[tag].observe(on_change, names="value") 394 395 def add_float_range( 396 self, 397 tag: str, 398 description: str, 399 vmin: float, 400 vmax: float, 401 *args, 402 remember_value=False, 403 on_change: Optional[callable] = None, 404 **kwargs, 405 ): 406 """ 407 @unified 408 Add a float slider widget to the container. 409 410 Parameters 411 ---------- 412 tag : str 413 Tag to identify the widget. 414 description : str 415 The message to display. 416 vmin : float 417 Minimum value of the slider. 418 vmax : float 419 Maximum value of the slider. 420 remember_value : bool, optional 421 Whether to remember the last selected value. Defaults to False. 422 *args : tuple 423 Additional positional arguments for the widget. 424 **kwargs : dict 425 Additional keyword arguments for the widget. 426 """ 427 if self.params is not None: 428 if tag in self.params and vmin <= self.params[tag] <= vmax: 429 kwargs["value"] = self.params[tag] 430 elif ( 431 remember_value 432 and tag in self.cfg 433 and vmin <= self.cfg[tag] <= vmax 434 ): 435 kwargs["value"] = int(self.cfg[tag]) 436 style = kwargs.pop("style", self._style) 437 self.elements[tag] = widgets.FloatSlider( 438 description=description, 439 min=vmin, 440 max=vmax, 441 *args, 442 **kwargs, 443 layout=self._layout, 444 style=style, 445 ) 446 447 if on_change is not None: 448 self.elements[tag].observe(on_change, names="value") 449 450 def add_float_slider( 451 self, 452 tag: str, 453 description: str, 454 min: int, 455 max: int, 456 *args, 457 remember_value=False, 458 on_change: Optional[callable] = None, 459 **kwargs, 460 ): 461 """ 462 @jupyter 463 Add an float slider widget to the container. 464 465 Parameters 466 ---------- 467 tag : str 468 Tag to identify the widget. 469 description : str 470 The message to display. 471 min : float 472 Minimum value of the slider. 473 max : float 474 Maximum value of the slider. 475 remember_value : bool, optional 476 Whether to remember the last selected value. Defaults to False. 477 *args : tuple 478 Additional positional arguments for the widget. 479 **kwargs : dict 480 Additional keyword arguments for the widget. 481 """ 482 self.add_float_range( 483 tag, 484 description, 485 vmin=min, 486 vmax=max, 487 *args, 488 remember_value=remember_value, 489 **kwargs, 490 ) 491 492 if on_change is not None: 493 self.elements[tag].observe(on_change, names="value") 494 495 def add_check( 496 self, 497 tag: str, 498 description: str, 499 *args, 500 remember_value=False, 501 on_change: Optional[callable] = None, 502 **kwargs, 503 ): 504 """ 505 @unified 506 Add a checkbox widget to the container. 507 508 Parameters 509 ---------- 510 tag : str 511 Tag to identify the widget. 512 description : str 513 The message to display. 514 remember_value : bool, optional 515 Whether to remember the last selected value. Defaults to False. 516 *args : tuple 517 Additional positional arguments for the widget. 518 **kwargs : dict 519 Additional keyword arguments for the widget. 520 """ 521 if self.params is not None: 522 if tag in self.params: 523 kwargs["value"] = self.params[tag] 524 elif remember_value and tag in self.cfg: 525 kwargs["value"] = self.cfg[tag] 526 style = kwargs.pop("style", self._style) 527 self.elements[tag] = widgets.Checkbox( 528 description=description, 529 *args, 530 **kwargs, 531 layout=self._layout, 532 style=style, 533 ) 534 535 if on_change is not None: 536 self.elements[tag].observe(on_change, names="value") 537 538 def add_int_text( 539 self, 540 tag, 541 description: str = "", 542 *args, 543 remember_value=False, 544 on_change: Optional[callable] = None, 545 **kwargs, 546 ): 547 """ 548 @unified 549 Add an integer text widget to the container. 550 551 Parameters 552 ---------- 553 tag : str 554 Tag to identify the widget. 555 description : str, optional 556 The message to display. Defaults to "". 557 remember_value : bool, optional 558 Whether to remember the last entered value. Defaults to False. 559 *args : tuple 560 Additional positional arguments for the widget. 561 **kwargs : dict 562 Additional keyword arguments for the widget. 563 """ 564 if self.params is not None: 565 if tag in self.params: 566 kwargs["value"] = self.params[tag] 567 elif remember_value and tag in self.cfg: 568 kwargs["value"] = self.cfg[tag] 569 570 style = kwargs.pop("style", self._style) 571 self.elements[tag] = widgets.IntText( 572 description=description, 573 *args, 574 **kwargs, 575 layout=self._layout, 576 style=style, 577 ) 578 579 if on_change is not None: 580 self.elements[tag].observe(on_change, names="value") 581 582 def add_bounded_int_text( 583 self, 584 tag, 585 description: str, 586 vmin: int, 587 vmax: int, 588 *args, 589 remember_value=False, 590 on_change: Optional[callable] = None, 591 **kwargs, 592 ): 593 """ 594 @unified 595 Add a bounded integer text widget to the container. 596 597 Parameters 598 ---------- 599 tag : str 600 Tag to identify the widget. 601 description : str 602 The message to display. 603 vmin : int 604 Minimum value of the input field. 605 vmax : int 606 Maximum value of the input field. 607 remember_value : bool, optional 608 Whether to remember the last entered value. Defaults to False. 609 *args : tuple 610 Additional positional arguments for the widget. 611 **kwargs : dict 612 Additional keyword arguments for the widget. 613 """ 614 if self.params is not None: 615 if tag in self.params: 616 kwargs["value"] = self.params[tag] 617 elif remember_value and tag in self.cfg: 618 kwargs["value"] = self.cfg[tag] 619 style = kwargs.pop("style", self._style) 620 self.elements[tag] = widgets.BoundedIntText( 621 min=vmin, 622 max=vmax, 623 description=description, 624 *args, 625 **kwargs, 626 layout=self._layout, 627 style=style, 628 ) 629 630 if on_change is not None: 631 self.elements[tag].observe(on_change, names="value") 632 633 def add_float_text( 634 self, 635 tag, 636 description: str = "", 637 *args, 638 remember_value=False, 639 on_change: Optional[callable] = None, 640 **kwargs, 641 ): 642 """ 643 @unified 644 Add a float text widget to the container. 645 646 Parameters 647 ---------- 648 tag : str 649 Tag to identify the widget. 650 description : str, optional 651 The message to display. Defaults to "". 652 remember_value : bool, optional 653 Whether to remember the last entered value. Defaults to False. 654 *args : tuple 655 Additional positional arguments for the widget. 656 **kwargs : dict 657 Additional keyword arguments for the widget. 658 """ 659 if self.params is not None: 660 if tag in self.params: 661 kwargs["value"] = self.params[tag] 662 elif remember_value and tag in self.cfg: 663 kwargs["value"] = self.cfg[tag] 664 style = kwargs.pop("style", self._style) 665 self.elements[tag] = widgets.FloatText( 666 description=description, 667 *args, 668 **kwargs, 669 layout=self._layout, 670 style=style, 671 ) 672 673 if on_change is not None: 674 self.elements[tag].observe(on_change, names="value") 675 676 def add_bounded_float_text( 677 self, 678 tag, 679 description: str, 680 vmin: int, 681 vmax: int, 682 *args, 683 remember_value=False, 684 on_change: Optional[callable] = None, 685 **kwargs, 686 ): 687 """ 688 @unified 689 Add a bounded float text widget to the container. 690 691 Parameters 692 ---------- 693 tag : str 694 Tag to identify the widget. 695 description : str 696 The message to display. 697 vmin : int 698 Minimum value of the input field. 699 vmax : int 700 Maximum value of the input field. 701 remember_value : bool, optional 702 Whether to remember the last entered value. Defaults to False. 703 *args : tuple 704 Additional positional arguments for the widget. 705 **kwargs : dict 706 Additional keyword arguments for the widget. 707 """ 708 if self.params is not None: 709 if tag in self.params: 710 kwargs["value"] = self.params[tag] 711 elif remember_value and tag in self.cfg: 712 kwargs["value"] = self.cfg[tag] 713 style = kwargs.pop("style", self._style) 714 self.elements[tag] = widgets.BoundedFloatText( 715 min=vmin, 716 max=vmax, 717 description=description, 718 *args, 719 **kwargs, 720 layout=self._layout, 721 style=style, 722 ) 723 724 if on_change is not None: 725 self.elements[tag].observe(on_change, names="value") 726 727 def add_dropdown( 728 self, 729 tag, 730 options: list, 731 description: str = "", 732 *args, 733 remember_value=False, 734 on_change: Optional[callable] = None, 735 **kwargs, 736 ): 737 """ 738 @unified 739 Add a dropdown widget to the container. 740 741 Parameters 742 ---------- 743 tag : str 744 Tag to identify the widget. 745 options : list 746 List of choices for the dropdown. 747 description : str, optional 748 The message to display. Defaults to "". 749 remember_value : bool, optional 750 Whether to remember the last selected value. Defaults to False. 751 *args : tuple 752 Additional positional arguments for the widget. 753 **kwargs : dict 754 Additional keyword arguments for the widget. 755 """ 756 if remember_value and tag in self.cfg and self.cfg[tag] in options: 757 kwargs["value"] = self.cfg[tag] 758 if self.params is not None: 759 if tag in self.params: 760 kwargs["value"] = self.params[tag] 761 style = kwargs.pop("style", self._style) 762 self.elements[tag] = widgets.Dropdown( 763 options=options, 764 description=description, 765 *args, 766 **kwargs, 767 layout=self._layout, 768 style=style, 769 ) 770 771 if on_change is not None: 772 self.elements[tag].observe(on_change, names="value") 773 774 def add_checkbox( 775 self, 776 tag: str, 777 description: str, 778 *args, 779 remember_value=False, 780 on_change: Optional[callable] = None, 781 **kwargs, 782 ): 783 """ 784 @jupyter 785 Add a checkbox widget to the container. 786 787 Parameters 788 ---------- 789 tag : str 790 Tag to identify the widget. 791 description : str 792 The message to display. 793 remember_value : bool, optional 794 Whether to remember the last selected value. Defaults to False. 795 *args : tuple 796 Additional positional arguments for the widget. 797 **kwargs : dict 798 Additional keyword arguments for the widget. 799 """ 800 self.add_check( 801 tag, 802 description=description, 803 remember_value=remember_value, 804 *args, 805 **kwargs, 806 ) 807 808 if on_change is not None: 809 self.elements[tag].observe(on_change, names="value") 810 811 def add_select_multiple( 812 self, tag: str, options: list, description: str = "", *args, **kwargs 813 ): 814 """ 815 @jupyter 816 Add a multiple selection widget to the container. 817 818 Parameters 819 ---------- 820 tag : str 821 Tag to identify the widget. 822 options : list 823 List of choices for the selection. 824 *args : tuple 825 Additional positional arguments for the widget. 826 **kwargs : dict 827 Additional keyword arguments for the widget. 828 """ 829 style = kwargs.pop("style", self._style) 830 self.elements[tag] = widgets.SelectMultiple( 831 options=options, 832 description=description, 833 *args, 834 **kwargs, 835 layout=self._layout, 836 style=style, 837 ) 838 839 def add_file_upload( 840 self, tag, *args, accept=None, multiple=False, **kwargs 841 ): 842 """ 843 @jupyter 844 Add a file upload widget to the container. 845 846 Parameters 847 ---------- 848 tag : str 849 Tag to identify the widget. 850 accept : str, optional 851 The file types to accept. Defaults to None. 852 multiple : bool, optional 853 Allow multiple files to be uploaded. Defaults to False. 854 *args : tuple 855 Additional positional arguments for the widget. 856 **kwargs : dict 857 Additional keyword arguments for the widget. 858 """ 859 self.elements[tag] = FileChooser() 860 if accept is not None: 861 self.elements[tag].filter_pattern = accept 862 863 def add_output(self, tag: str, *args, **kwargs): 864 """ 865 @unified 866 Add an output widget to the container. 867 868 Parameters 869 ---------- 870 tag : str 871 Tag to identify the widget. 872 *args : tuple 873 Additional positional arguments for the widget. 874 **kwargs : dict 875 Additional keyword arguments for the widget. 876 """ 877 style = kwargs.pop("style", self._style) 878 self.elements[tag] = widgets.Output( 879 *args, 880 **kwargs, 881 layout=self._layout, 882 style=style, 883 ) 884 885 def add_custom_widget( 886 self, 887 tag: str, 888 custom_widget, 889 *args, 890 remember_value=False, 891 on_change: Optional[callable] = None, 892 **kwargs, 893 ): 894 """ 895 @jupyter 896 Add a custom widget to the container. 897 Parameters 898 ---------- 899 tag : str 900 Tag to identify the widget. 901 custom_widget : ipywidget to add 902 The custom widget to add. 903 *args : tuple 904 Additional positional arguments for the widget. 905 **kwargs : dict 906 Additional keyword arguments for the widget. 907 """ 908 if self.params is not None: 909 if tag in self.params: 910 kwargs["value"] = self.params[tag] 911 elif remember_value and tag in self.cfg: 912 kwargs["value"] = self.cfg[tag] 913 style = kwargs.pop("style", self._style) 914 self.elements[tag] = custom_widget( 915 *args, 916 **kwargs, 917 layout=self._layout, 918 style=style, 919 ) 920 921 if on_change is not None: 922 self.elements[tag].observe(on_change, names="value") 923 924 def save_parameters(self, path: str): 925 """ 926 @unified 927 Save the widget values to a file. 928 929 Parameters 930 ---------- 931 path : str 932 The path to save the file. 933 """ 934 if not path.endswith(".yml"): 935 path += f"{self.title}_parameters.yml" 936 out = {} 937 for tag in self.elements: 938 if tag.startswith("label_"): 939 pass 940 elif hasattr(self.elements[tag], "value"): 941 out[tag] = self.elements[tag].value 942 with open(path, "w") as f: 943 yaml.dump(out, f) 944 945 def save_settings(self): 946 """ 947 @unified 948 Save the widget values to the configuration file. 949 """ 950 for tag in self.elements: 951 if tag.startswith("label_"): 952 pass 953 elif hasattr(self.elements[tag], "value"): 954 if type(self.elements[tag].value) != tuple: 955 self.cfg[tag] = self.elements[tag].value 956 config_file = CONFIG_PATH / f"{self.title}.yml" 957 config_file.parent.mkdir(exist_ok=True) 958 959 base_config = self._get_config(self.title) # loads the config file 960 for key, value in self.cfg.items(): 961 base_config[key] = value 962 963 with open(config_file, "w") as f: 964 yaml.dump(base_config, f) 965 966 def show(self): 967 """ 968 @unified 969 Display the widgets in the container. 970 """ 971 self._main_display.children = tuple(self.elements.values()) 972 clear_output() 973 display(self._main_display) 974 975 def clear_elements(self): 976 """ 977 @unified 978 Clear all widgets from the container. 979 """ 980 self.elements = {} 981 self._nLabels = 0 982 self._main_display.children = () 983 984 def _get_config(self, title: Optional[str]) -> dict: 985 """ 986 Get the configuration dictionary without needing to initialize the GUI. 987 988 Parameters 989 ---------- 990 title : str, optional 991 The title of the GUI. If None, returns the entire configuration. 992 993 Returns 994 ------- 995 dict 996 The configuration dictionary. 997 """ 998 999 config_file = CONFIG_PATH / f"{title}.yml" 1000 1001 if not config_file.exists(): 1002 return {} 1003 1004 with open(config_file, "r") as f: 1005 return yaml.load(f, Loader=yaml.SafeLoader)
A class to create GUIs in Jupyter notebooks using ipywidgets
.
Parameters
title : str, optional Title of the GUI, used to store settings. Defaults to "basic_gui". width : str, optional Width of the widget container. Defaults to "50%".
33 def __init__(self, title="basic_gui", width="50%"): 34 """ 35 Container for widgets. 36 37 Parameters 38 ---------- 39 title : str, optional 40 The title of the widget container, used to store settings. 41 width : str, optional 42 The width of the widget container. 43 """ 44 pass
Container for widgets.
Parameters
title : str, optional The title of the widget container, used to store settings. width : str, optional The width of the widget container.
90 def add_label(self, value="", *args, **kwargs): 91 """ 92 @unified 93 Add a label widget to the container. 94 95 Parameters 96 ---------- 97 label : str, optional 98 The label text to display. Defaults to "". 99 *args : tuple 100 Additional positional arguments for the widget. 101 **kwargs : dict 102 Additional keyword arguments for the widget. 103 """ 104 self._nLabels += 1 105 style = kwargs.pop("style", self._style) 106 self.elements[f"label_{self._nLabels}"] = widgets.Label( 107 value=value, 108 *args, 109 **kwargs, 110 layout=self._layout, 111 style=style, 112 )
@unified Add a label widget to the container.
Parameters
label : str, optional The label text to display. Defaults to "". args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
114 def add_text( 115 self, 116 tag: str, 117 description: str = "", 118 placeholder: str = "", 119 *args, 120 remember_value=False, 121 **kwargs, 122 ): 123 """ 124 @unified 125 Add a text widget to the container. 126 127 Parameters 128 ---------- 129 tag : str 130 Tag to identify the widget. 131 description : str, optional 132 The message to display. Defaults to "". 133 placeholder : str, optional 134 Placeholder text for the input field. Defaults to "". 135 remember_value : bool, optional 136 Whether to remember the last entered value. Defaults to False. 137 *args : tuple 138 Additional positional arguments for the widget. 139 **kwargs : dict 140 Additional keyword arguments for the widget. 141 """ 142 if self.params is not None: 143 if tag in self.params: 144 kwargs["value"] = self.params[tag] 145 elif remember_value and tag in self.cfg: 146 kwargs["value"] = str(self.cfg[tag]) 147 148 style = kwargs.pop("style", self._style) 149 self.elements[tag] = widgets.Text( 150 description=description, 151 placeholder=placeholder, 152 *args, 153 **kwargs, 154 layout=self._layout, 155 style=style, 156 )
@unified Add a text widget to the container.
Parameters
tag : str Tag to identify the widget. description : str, optional The message to display. Defaults to "". placeholder : str, optional Placeholder text for the input field. Defaults to "". remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
158 def add_callback( 159 self, tag, func, values: dict, description="Run", *args, **kwargs 160 ): 161 """ 162 @unified 163 Add a button widget to the container. 164 165 Parameters 166 ---------- 167 tag : str 168 Tag to identify the widget. 169 func : callable 170 The function to call when the button is clicked. 171 values : dict 172 Dictionary of widget values to pass to the callback function. 173 description : str, optional 174 The label for the button. Defaults to "Run". 175 *args : tuple 176 Additional positional arguments for the button. 177 **kwargs : dict 178 Additional keyword arguments for the button. 179 """ 180 style = kwargs.pop("style", self._style) 181 self.elements[tag] = widgets.Button( 182 description=description, 183 *args, 184 **kwargs, 185 layout=self._layout, 186 style=style, 187 ) 188 189 def wrapped(button): 190 self.save_settings() 191 func(values) 192 193 self.elements[tag].on_click(wrapped)
@unified Add a button widget to the container.
Parameters
tag : str Tag to identify the widget. func : callable The function to call when the button is clicked. values : dict Dictionary of widget values to pass to the callback function. description : str, optional The label for the button. Defaults to "Run". args : tuple Additional positional arguments for the button. *kwargs : dict Additional keyword arguments for the button.
220 def add_text_area( 221 self, 222 tag: str, 223 description: str = "", 224 placeholder: str = "", 225 *args, 226 remember_value=False, 227 on_change: Optional[callable] = None, 228 **kwargs, 229 ): 230 """ 231 @unified 232 Add a textarea widget to the container. 233 234 Parameters 235 ---------- 236 tag : str 237 Tag to identify the widget. 238 description : str, optional 239 The message to display. Defaults to "". 240 placeholder : str, optional 241 Placeholder text for the input field. Defaults to "". 242 remember_value : bool, optional 243 Whether to remember the last entered value. Defaults to False. 244 *args : tuple 245 Additional positional arguments for the widget. 246 **kwargs : dict 247 Additional keyword arguments for the widget. 248 """ 249 if self.params is not None: 250 if tag in self.params: 251 kwargs["value"] = self.params[tag] 252 elif remember_value and tag in self.cfg: 253 kwargs["value"] = str(self.cfg[tag]) 254 style = kwargs.pop("style", self._style) 255 self.elements[tag] = widgets.Textarea( 256 description=description, 257 placeholder=placeholder, 258 *args, 259 **kwargs, 260 layout=self._layout, 261 style=style, 262 ) 263 264 if on_change is not None: 265 self.elements[tag].observe(on_change, names="value")
@unified Add a textarea widget to the container.
Parameters
tag : str Tag to identify the widget. description : str, optional The message to display. Defaults to "". placeholder : str, optional Placeholder text for the input field. Defaults to "". remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
267 def add_HTML( 268 self, tag: str, value: str, description: str = "", *args, **kwargs 269 ): 270 """ 271 @jupyter 272 Add an HTML widget to the container. 273 274 Parameters 275 ---------- 276 tag : str 277 Tag to identify the widget. 278 value : str 279 The HTML content to display. 280 *args : tuple 281 Additional positional arguments for the widget. 282 **kwargs : dict 283 Additional keyword arguments for the widget. 284 """ 285 style = kwargs.pop("style", self._style) 286 self.elements[tag] = widgets.HTML( 287 value=value, 288 description=description, 289 *args, 290 **kwargs, 291 layout=self._layout, 292 style=style, 293 )
@jupyter Add an HTML widget to the container.
Parameters
tag : str Tag to identify the widget. value : str The HTML content to display. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
295 def add_int_range( 296 self, 297 tag: str, 298 description: str, 299 vmin: int, 300 vmax: int, 301 *args, 302 remember_value=False, 303 on_change: Optional[callable] = None, 304 **kwargs, 305 ): 306 """ 307 @unified 308 Add an integer slider widget to the container. 309 310 Parameters 311 ---------- 312 tag : str 313 Tag to identify the widget. 314 description : str 315 The message to display. 316 vmin : int 317 Minimum value of the slider. 318 vmax : int 319 Maximum value of the slider. 320 remember_value : bool, optional 321 Whether to remember the last selected value. Defaults to False. 322 *args : tuple 323 Additional positional arguments for the widget. 324 **kwargs : dict 325 Additional keyword arguments for the widget. 326 """ 327 if self.params is not None: 328 if tag in self.params and vmin <= self.params[tag] <= vmax: 329 kwargs["value"] = self.params[tag] 330 elif ( 331 remember_value 332 and tag in self.cfg 333 and vmin <= self.cfg[tag] <= vmax 334 ): 335 kwargs["value"] = int(self.cfg[tag]) 336 style = kwargs.pop("style", self._style) 337 self.elements[tag] = widgets.IntSlider( 338 description=description, 339 min=vmin, 340 max=vmax, 341 *args, 342 **kwargs, 343 layout=self._layout, 344 style=style, 345 ) 346 347 if on_change is not None: 348 self.elements[tag].observe(on_change, names="value")
@unified Add an integer slider widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. vmin : int Minimum value of the slider. vmax : int Maximum value of the slider. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
350 def add_int_slider( 351 self, 352 tag: str, 353 description: str, 354 min: int, 355 max: int, 356 *args, 357 remember_value=False, 358 on_change: Optional[callable] = None, 359 **kwargs, 360 ): 361 """ 362 @jupyter 363 Add an integer slider widget to the container. 364 365 Parameters 366 ---------- 367 tag : str 368 Tag to identify the widget. 369 description : str 370 The message to display. 371 vmin : int 372 Minimum value of the slider. 373 vmax : int 374 Maximum value of the slider. 375 remember_value : bool, optional 376 Whether to remember the last selected value. Defaults to False. 377 *args : tuple 378 Additional positional arguments for the widget. 379 **kwargs : dict 380 Additional keyword arguments for the widget. 381 """ 382 self.add_int_range( 383 tag, 384 description, 385 vmin=min, 386 vmax=max, 387 *args, 388 remember_value=remember_value, 389 **kwargs, 390 ) 391 392 if on_change is not None: 393 self.elements[tag].observe(on_change, names="value")
@jupyter Add an integer slider widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. vmin : int Minimum value of the slider. vmax : int Maximum value of the slider. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
395 def add_float_range( 396 self, 397 tag: str, 398 description: str, 399 vmin: float, 400 vmax: float, 401 *args, 402 remember_value=False, 403 on_change: Optional[callable] = None, 404 **kwargs, 405 ): 406 """ 407 @unified 408 Add a float slider widget to the container. 409 410 Parameters 411 ---------- 412 tag : str 413 Tag to identify the widget. 414 description : str 415 The message to display. 416 vmin : float 417 Minimum value of the slider. 418 vmax : float 419 Maximum value of the slider. 420 remember_value : bool, optional 421 Whether to remember the last selected value. Defaults to False. 422 *args : tuple 423 Additional positional arguments for the widget. 424 **kwargs : dict 425 Additional keyword arguments for the widget. 426 """ 427 if self.params is not None: 428 if tag in self.params and vmin <= self.params[tag] <= vmax: 429 kwargs["value"] = self.params[tag] 430 elif ( 431 remember_value 432 and tag in self.cfg 433 and vmin <= self.cfg[tag] <= vmax 434 ): 435 kwargs["value"] = int(self.cfg[tag]) 436 style = kwargs.pop("style", self._style) 437 self.elements[tag] = widgets.FloatSlider( 438 description=description, 439 min=vmin, 440 max=vmax, 441 *args, 442 **kwargs, 443 layout=self._layout, 444 style=style, 445 ) 446 447 if on_change is not None: 448 self.elements[tag].observe(on_change, names="value")
@unified Add a float slider widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. vmin : float Minimum value of the slider. vmax : float Maximum value of the slider. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
450 def add_float_slider( 451 self, 452 tag: str, 453 description: str, 454 min: int, 455 max: int, 456 *args, 457 remember_value=False, 458 on_change: Optional[callable] = None, 459 **kwargs, 460 ): 461 """ 462 @jupyter 463 Add an float slider widget to the container. 464 465 Parameters 466 ---------- 467 tag : str 468 Tag to identify the widget. 469 description : str 470 The message to display. 471 min : float 472 Minimum value of the slider. 473 max : float 474 Maximum value of the slider. 475 remember_value : bool, optional 476 Whether to remember the last selected value. Defaults to False. 477 *args : tuple 478 Additional positional arguments for the widget. 479 **kwargs : dict 480 Additional keyword arguments for the widget. 481 """ 482 self.add_float_range( 483 tag, 484 description, 485 vmin=min, 486 vmax=max, 487 *args, 488 remember_value=remember_value, 489 **kwargs, 490 ) 491 492 if on_change is not None: 493 self.elements[tag].observe(on_change, names="value")
@jupyter Add an float slider widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. min : float Minimum value of the slider. max : float Maximum value of the slider. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
495 def add_check( 496 self, 497 tag: str, 498 description: str, 499 *args, 500 remember_value=False, 501 on_change: Optional[callable] = None, 502 **kwargs, 503 ): 504 """ 505 @unified 506 Add a checkbox widget to the container. 507 508 Parameters 509 ---------- 510 tag : str 511 Tag to identify the widget. 512 description : str 513 The message to display. 514 remember_value : bool, optional 515 Whether to remember the last selected value. Defaults to False. 516 *args : tuple 517 Additional positional arguments for the widget. 518 **kwargs : dict 519 Additional keyword arguments for the widget. 520 """ 521 if self.params is not None: 522 if tag in self.params: 523 kwargs["value"] = self.params[tag] 524 elif remember_value and tag in self.cfg: 525 kwargs["value"] = self.cfg[tag] 526 style = kwargs.pop("style", self._style) 527 self.elements[tag] = widgets.Checkbox( 528 description=description, 529 *args, 530 **kwargs, 531 layout=self._layout, 532 style=style, 533 ) 534 535 if on_change is not None: 536 self.elements[tag].observe(on_change, names="value")
@unified Add a checkbox widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
538 def add_int_text( 539 self, 540 tag, 541 description: str = "", 542 *args, 543 remember_value=False, 544 on_change: Optional[callable] = None, 545 **kwargs, 546 ): 547 """ 548 @unified 549 Add an integer text widget to the container. 550 551 Parameters 552 ---------- 553 tag : str 554 Tag to identify the widget. 555 description : str, optional 556 The message to display. Defaults to "". 557 remember_value : bool, optional 558 Whether to remember the last entered value. Defaults to False. 559 *args : tuple 560 Additional positional arguments for the widget. 561 **kwargs : dict 562 Additional keyword arguments for the widget. 563 """ 564 if self.params is not None: 565 if tag in self.params: 566 kwargs["value"] = self.params[tag] 567 elif remember_value and tag in self.cfg: 568 kwargs["value"] = self.cfg[tag] 569 570 style = kwargs.pop("style", self._style) 571 self.elements[tag] = widgets.IntText( 572 description=description, 573 *args, 574 **kwargs, 575 layout=self._layout, 576 style=style, 577 ) 578 579 if on_change is not None: 580 self.elements[tag].observe(on_change, names="value")
@unified Add an integer text widget to the container.
Parameters
tag : str Tag to identify the widget. description : str, optional The message to display. Defaults to "". remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
582 def add_bounded_int_text( 583 self, 584 tag, 585 description: str, 586 vmin: int, 587 vmax: int, 588 *args, 589 remember_value=False, 590 on_change: Optional[callable] = None, 591 **kwargs, 592 ): 593 """ 594 @unified 595 Add a bounded integer text widget to the container. 596 597 Parameters 598 ---------- 599 tag : str 600 Tag to identify the widget. 601 description : str 602 The message to display. 603 vmin : int 604 Minimum value of the input field. 605 vmax : int 606 Maximum value of the input field. 607 remember_value : bool, optional 608 Whether to remember the last entered value. Defaults to False. 609 *args : tuple 610 Additional positional arguments for the widget. 611 **kwargs : dict 612 Additional keyword arguments for the widget. 613 """ 614 if self.params is not None: 615 if tag in self.params: 616 kwargs["value"] = self.params[tag] 617 elif remember_value and tag in self.cfg: 618 kwargs["value"] = self.cfg[tag] 619 style = kwargs.pop("style", self._style) 620 self.elements[tag] = widgets.BoundedIntText( 621 min=vmin, 622 max=vmax, 623 description=description, 624 *args, 625 **kwargs, 626 layout=self._layout, 627 style=style, 628 ) 629 630 if on_change is not None: 631 self.elements[tag].observe(on_change, names="value")
@unified Add a bounded integer text widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. vmin : int Minimum value of the input field. vmax : int Maximum value of the input field. remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
633 def add_float_text( 634 self, 635 tag, 636 description: str = "", 637 *args, 638 remember_value=False, 639 on_change: Optional[callable] = None, 640 **kwargs, 641 ): 642 """ 643 @unified 644 Add a float text widget to the container. 645 646 Parameters 647 ---------- 648 tag : str 649 Tag to identify the widget. 650 description : str, optional 651 The message to display. Defaults to "". 652 remember_value : bool, optional 653 Whether to remember the last entered value. Defaults to False. 654 *args : tuple 655 Additional positional arguments for the widget. 656 **kwargs : dict 657 Additional keyword arguments for the widget. 658 """ 659 if self.params is not None: 660 if tag in self.params: 661 kwargs["value"] = self.params[tag] 662 elif remember_value and tag in self.cfg: 663 kwargs["value"] = self.cfg[tag] 664 style = kwargs.pop("style", self._style) 665 self.elements[tag] = widgets.FloatText( 666 description=description, 667 *args, 668 **kwargs, 669 layout=self._layout, 670 style=style, 671 ) 672 673 if on_change is not None: 674 self.elements[tag].observe(on_change, names="value")
@unified Add a float text widget to the container.
Parameters
tag : str Tag to identify the widget. description : str, optional The message to display. Defaults to "". remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
676 def add_bounded_float_text( 677 self, 678 tag, 679 description: str, 680 vmin: int, 681 vmax: int, 682 *args, 683 remember_value=False, 684 on_change: Optional[callable] = None, 685 **kwargs, 686 ): 687 """ 688 @unified 689 Add a bounded float text widget to the container. 690 691 Parameters 692 ---------- 693 tag : str 694 Tag to identify the widget. 695 description : str 696 The message to display. 697 vmin : int 698 Minimum value of the input field. 699 vmax : int 700 Maximum value of the input field. 701 remember_value : bool, optional 702 Whether to remember the last entered value. Defaults to False. 703 *args : tuple 704 Additional positional arguments for the widget. 705 **kwargs : dict 706 Additional keyword arguments for the widget. 707 """ 708 if self.params is not None: 709 if tag in self.params: 710 kwargs["value"] = self.params[tag] 711 elif remember_value and tag in self.cfg: 712 kwargs["value"] = self.cfg[tag] 713 style = kwargs.pop("style", self._style) 714 self.elements[tag] = widgets.BoundedFloatText( 715 min=vmin, 716 max=vmax, 717 description=description, 718 *args, 719 **kwargs, 720 layout=self._layout, 721 style=style, 722 ) 723 724 if on_change is not None: 725 self.elements[tag].observe(on_change, names="value")
@unified Add a bounded float text widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. vmin : int Minimum value of the input field. vmax : int Maximum value of the input field. remember_value : bool, optional Whether to remember the last entered value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
727 def add_dropdown( 728 self, 729 tag, 730 options: list, 731 description: str = "", 732 *args, 733 remember_value=False, 734 on_change: Optional[callable] = None, 735 **kwargs, 736 ): 737 """ 738 @unified 739 Add a dropdown widget to the container. 740 741 Parameters 742 ---------- 743 tag : str 744 Tag to identify the widget. 745 options : list 746 List of choices for the dropdown. 747 description : str, optional 748 The message to display. Defaults to "". 749 remember_value : bool, optional 750 Whether to remember the last selected value. Defaults to False. 751 *args : tuple 752 Additional positional arguments for the widget. 753 **kwargs : dict 754 Additional keyword arguments for the widget. 755 """ 756 if remember_value and tag in self.cfg and self.cfg[tag] in options: 757 kwargs["value"] = self.cfg[tag] 758 if self.params is not None: 759 if tag in self.params: 760 kwargs["value"] = self.params[tag] 761 style = kwargs.pop("style", self._style) 762 self.elements[tag] = widgets.Dropdown( 763 options=options, 764 description=description, 765 *args, 766 **kwargs, 767 layout=self._layout, 768 style=style, 769 ) 770 771 if on_change is not None: 772 self.elements[tag].observe(on_change, names="value")
@unified Add a dropdown widget to the container.
Parameters
tag : str Tag to identify the widget. options : list List of choices for the dropdown. description : str, optional The message to display. Defaults to "". remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
774 def add_checkbox( 775 self, 776 tag: str, 777 description: str, 778 *args, 779 remember_value=False, 780 on_change: Optional[callable] = None, 781 **kwargs, 782 ): 783 """ 784 @jupyter 785 Add a checkbox widget to the container. 786 787 Parameters 788 ---------- 789 tag : str 790 Tag to identify the widget. 791 description : str 792 The message to display. 793 remember_value : bool, optional 794 Whether to remember the last selected value. Defaults to False. 795 *args : tuple 796 Additional positional arguments for the widget. 797 **kwargs : dict 798 Additional keyword arguments for the widget. 799 """ 800 self.add_check( 801 tag, 802 description=description, 803 remember_value=remember_value, 804 *args, 805 **kwargs, 806 ) 807 808 if on_change is not None: 809 self.elements[tag].observe(on_change, names="value")
@jupyter Add a checkbox widget to the container.
Parameters
tag : str Tag to identify the widget. description : str The message to display. remember_value : bool, optional Whether to remember the last selected value. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
811 def add_select_multiple( 812 self, tag: str, options: list, description: str = "", *args, **kwargs 813 ): 814 """ 815 @jupyter 816 Add a multiple selection widget to the container. 817 818 Parameters 819 ---------- 820 tag : str 821 Tag to identify the widget. 822 options : list 823 List of choices for the selection. 824 *args : tuple 825 Additional positional arguments for the widget. 826 **kwargs : dict 827 Additional keyword arguments for the widget. 828 """ 829 style = kwargs.pop("style", self._style) 830 self.elements[tag] = widgets.SelectMultiple( 831 options=options, 832 description=description, 833 *args, 834 **kwargs, 835 layout=self._layout, 836 style=style, 837 )
@jupyter Add a multiple selection widget to the container.
Parameters
tag : str Tag to identify the widget. options : list List of choices for the selection. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
839 def add_file_upload( 840 self, tag, *args, accept=None, multiple=False, **kwargs 841 ): 842 """ 843 @jupyter 844 Add a file upload widget to the container. 845 846 Parameters 847 ---------- 848 tag : str 849 Tag to identify the widget. 850 accept : str, optional 851 The file types to accept. Defaults to None. 852 multiple : bool, optional 853 Allow multiple files to be uploaded. Defaults to False. 854 *args : tuple 855 Additional positional arguments for the widget. 856 **kwargs : dict 857 Additional keyword arguments for the widget. 858 """ 859 self.elements[tag] = FileChooser() 860 if accept is not None: 861 self.elements[tag].filter_pattern = accept
@jupyter Add a file upload widget to the container.
Parameters
tag : str Tag to identify the widget. accept : str, optional The file types to accept. Defaults to None. multiple : bool, optional Allow multiple files to be uploaded. Defaults to False. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
863 def add_output(self, tag: str, *args, **kwargs): 864 """ 865 @unified 866 Add an output widget to the container. 867 868 Parameters 869 ---------- 870 tag : str 871 Tag to identify the widget. 872 *args : tuple 873 Additional positional arguments for the widget. 874 **kwargs : dict 875 Additional keyword arguments for the widget. 876 """ 877 style = kwargs.pop("style", self._style) 878 self.elements[tag] = widgets.Output( 879 *args, 880 **kwargs, 881 layout=self._layout, 882 style=style, 883 )
@unified Add an output widget to the container.
Parameters
tag : str Tag to identify the widget. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
885 def add_custom_widget( 886 self, 887 tag: str, 888 custom_widget, 889 *args, 890 remember_value=False, 891 on_change: Optional[callable] = None, 892 **kwargs, 893 ): 894 """ 895 @jupyter 896 Add a custom widget to the container. 897 Parameters 898 ---------- 899 tag : str 900 Tag to identify the widget. 901 custom_widget : ipywidget to add 902 The custom widget to add. 903 *args : tuple 904 Additional positional arguments for the widget. 905 **kwargs : dict 906 Additional keyword arguments for the widget. 907 """ 908 if self.params is not None: 909 if tag in self.params: 910 kwargs["value"] = self.params[tag] 911 elif remember_value and tag in self.cfg: 912 kwargs["value"] = self.cfg[tag] 913 style = kwargs.pop("style", self._style) 914 self.elements[tag] = custom_widget( 915 *args, 916 **kwargs, 917 layout=self._layout, 918 style=style, 919 ) 920 921 if on_change is not None: 922 self.elements[tag].observe(on_change, names="value")
@jupyter Add a custom widget to the container.
Parameters
tag : str Tag to identify the widget. custom_widget : ipywidget to add The custom widget to add. args : tuple Additional positional arguments for the widget. *kwargs : dict Additional keyword arguments for the widget.
924 def save_parameters(self, path: str): 925 """ 926 @unified 927 Save the widget values to a file. 928 929 Parameters 930 ---------- 931 path : str 932 The path to save the file. 933 """ 934 if not path.endswith(".yml"): 935 path += f"{self.title}_parameters.yml" 936 out = {} 937 for tag in self.elements: 938 if tag.startswith("label_"): 939 pass 940 elif hasattr(self.elements[tag], "value"): 941 out[tag] = self.elements[tag].value 942 with open(path, "w") as f: 943 yaml.dump(out, f)
@unified Save the widget values to a file.
Parameters
path : str The path to save the file.
945 def save_settings(self): 946 """ 947 @unified 948 Save the widget values to the configuration file. 949 """ 950 for tag in self.elements: 951 if tag.startswith("label_"): 952 pass 953 elif hasattr(self.elements[tag], "value"): 954 if type(self.elements[tag].value) != tuple: 955 self.cfg[tag] = self.elements[tag].value 956 config_file = CONFIG_PATH / f"{self.title}.yml" 957 config_file.parent.mkdir(exist_ok=True) 958 959 base_config = self._get_config(self.title) # loads the config file 960 for key, value in self.cfg.items(): 961 base_config[key] = value 962 963 with open(config_file, "w") as f: 964 yaml.dump(base_config, f)
@unified Save the widget values to the configuration file.