From c4dc1f6547df0cca5b7adb842769f6908a2aa15b Mon Sep 17 00:00:00 2001 From: Davide Manzione Date: Mon, 24 Mar 2025 14:55:42 +0100 Subject: [PATCH 1/2] [038_limit_curves_selection], issue #38, Limited selection in listbox The listbox widget, where several curves can be selected to be plotted at once, now has a limited number of selectable items. In the 'PlotSettingsListBox', the 'MAX_SELECTABLE_ITEMS' attribute drives how many curves can be plotted. If more items than the admitted one are selected, only the number of items indicated by 'MAX_SELECTABLE_ITEMS' are actually shown as selected and can be plotted. Any further attempt to selected another item in the listbox widget does not produce any result. This limit has been introduced to cope with the fact that the plotting executable can produce a limited number of plot files. --- tugui/plot_settings.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/tugui/plot_settings.py b/tugui/plot_settings.py index f49e245..eb7f898 100644 --- a/tugui/plot_settings.py +++ b/tugui/plot_settings.py @@ -1,7 +1,7 @@ from enum import Enum import tkinter as tk from tkinter import ttk -from typing import Callable, List, Union +from typing import Callable, List, Tuple, Union class FieldType(Enum): @@ -163,6 +163,9 @@ class PlotSettingsListBox(): alternative values. This widget also presents a vertical scrollbar to help the inspection of the available values. """ + # Maximum number of items that can be selected in the list box + MAX_SELECTABLE_ITEMS: int = 10 + def __init__(self, container: ttk.Frame, label_text: str, choices: Union[List[str], None], row_index: int) -> None: """ @@ -199,6 +202,11 @@ def __init__(self, container: ttk.Frame, label_text: str, # Bind the selection of the listbox items event to a function call that stores the list of items self.choice_lb.bind("<>", self.store_selected) + # Initialize the tuple storing the currently selected indices + self.stored_indxs: Tuple[int] = () + # Declare a list holding the values to store, based on the selection + self.lb_selected_values: List[str] = [] + # Add an X-Y padding to all the widgets herein defined self.label.grid_configure(padx=5, pady=2) self.choice_lb.grid_configure(padx=5, pady=2) @@ -220,10 +228,26 @@ def store_selected(self, event: tk.Event = None) -> None: """ # Get the indices of the currently selected items indexes = self.choice_lb.curselection() - # Declare a list holding the values to store, based on the selection - self.lb_selected_values = list() + # Deselect the items if more than the maximum allowed items have been + # selected + if len(indexes) > self.MAX_SELECTABLE_ITEMS: + print("WARNING: only 10 items can be selected at once.") + # Store the first 10 elements + if len(self.stored_indxs) == 1: + self.stored_indxs = indexes[0:10] + # Get the indices of the items to be deselected + indxs = set(indexes) - set(self.stored_indxs) + if indxs: + # Deselect each item one by one + for i in indxs: + self.choice_lb.selection_clear(i, i) + else: + self.stored_indxs = indexes + + # Clear the list of selected values + self.lb_selected_values.clear() # Loop over all the indexes - for i in indexes: + for i in self.stored_indxs: # Fill the list of selected values of the listbox self.lb_selected_values.append(self.choice_lb.get(i)) From ab6f3647dd39156d1a90fa5a066e43bd6e096530 Mon Sep 17 00:00:00 2001 From: Davide Manzione Date: Mon, 7 Jul 2025 18:06:31 +0200 Subject: [PATCH 2/2] [038_limit_curves_selection], issue #38, Modified listbox selection logic as requested by reviewer --- tugui/plot_settings.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/tugui/plot_settings.py b/tugui/plot_settings.py index eb7f898..54e93db 100644 --- a/tugui/plot_settings.py +++ b/tugui/plot_settings.py @@ -232,15 +232,27 @@ def store_selected(self, event: tk.Event = None) -> None: # selected if len(indexes) > self.MAX_SELECTABLE_ITEMS: print("WARNING: only 10 items can be selected at once.") - # Store the first 10 elements - if len(self.stored_indxs) == 1: - self.stored_indxs = indexes[0:10] # Get the indices of the items to be deselected - indxs = set(indexes) - set(self.stored_indxs) - if indxs: - # Deselect each item one by one - for i in indxs: - self.choice_lb.selection_clear(i, i) + indxs = list(set(indexes) - set(self.stored_indxs)) + # Handle the case where the elements of the previous selection were + # lesser than the maximum allowable number + if len(self.stored_indxs) < self.MAX_SELECTABLE_ITEMS: + # Get the indexes to include depending on whether the first element + # in the next selection is before or after the last one of the + # previous selection + if indxs[0] > self.stored_indxs[-1]: + indxs_to_add = indxs[ + 0:self.MAX_SELECTABLE_ITEMS-len(self.stored_indxs)] + else: + indxs_to_add = indxs[ + len(self.stored_indxs)-self.MAX_SELECTABLE_ITEMS:] + # Update the stored indexes + self.stored_indxs = set(self.stored_indxs) | set(indxs_to_add) + # Get the indexes of the elements to deselect + indxs = set(indexes) - set(self.stored_indxs) + # Deselect each item one by one + for i in indxs: + self.choice_lb.selection_clear(i, i) else: self.stored_indxs = indexes