Source code for LabeledComboRow

import tkinter as tk
from tkinter import ttk

from gui.CreateTooltip import CreateTooltip


[docs] class LabeledComboRow(object): """ Builds one row of labeled dropdowns: an optional group label on top, followed by pairs of small field-labels and comboboxes. This is a small reusable building block used by UnitCellRegion.py in two ways: - A single instance for "unit cell growth" (x, y, z) - One instance per row for each Miller plane (h, k, l), created and destroyed dynamically by the "add plane" / "Remove Last" / "Remove All" buttons. """ def __init__(self, parent, input_label_list, option_ranges, group_label=None, group_tooltip=None, field_tooltips=None, bg="#e0e0e0", fg="black", padx=2, pady=2, combobox_width=5): """ :param parent: The parent widget this row's frame will be placed in. :param input_label_list: Small label text for each field, e.g. ["x:", "y:", "z:"]. :param option_ranges: List of (min, max) tuples, one per field. Defines the values shown in that field's dropdown, e.g. [(1, 5), (1, 5), (1, 5)]. :param group_label: Optional header text shown above the row, e.g. "Choose unit cell growth". If None, no header is shown (used for repeated rows like Miller planes). :param group_tooltip: Optional tooltip text attached to the group_label. :param field_tooltips: Optional list of tooltip strings, one per field. Leave as None to skip per-field tooltips (only the group_tooltip is shown). :param bg: Background color used for the frame and labels. :param fg: Text color used for the labels. :param padx: Horizontal padding around each field. :param pady: Vertical padding around each field. :param combobox_width: Width of each dropdown, in characters. """ if len(input_label_list) != len(option_ranges): raise ValueError("input_label_list and option_ranges must be the same length") self.frame = tk.Frame(master=parent, bg=bg) self.field_vars = [] # one StringVar per field, same order as input_label_list self.field_widgets = [] # the actual Combobox widgets, same order as input_label_list current_row = 0 # Optional header label, e.g. "Choose unit cell growth" if group_label: self.group_label_widget = tk.Label(master=self.frame, text=group_label, bg=bg, fg=fg) self.group_label_widget.grid(row=current_row, column=0, columnspan=len(input_label_list) * 2, sticky="w") if group_tooltip: CreateTooltip(self.group_label_widget, group_tooltip) current_row += 1 # Build one small label + combobox pair per field for index, field_label_text in enumerate(input_label_list): low, high = option_ranges[index] values = [str(v) for v in range(low, high + 1)] field_label = tk.Label(master=self.frame, text=field_label_text, bg=bg, fg=fg) field_label.grid(row=current_row, column=index * 2, padx=(padx, 2), pady=pady) # Default to 0 when it's a valid option (matches the old single-value defaults), # otherwise fall back to the lowest value in range. default_value = 0 if low <= 0 <= high else low field_var = tk.StringVar(value=str(default_value)) field_combobox = ttk.Combobox(master=self.frame, textvariable=field_var, values=values, width=combobox_width, state="readonly") field_combobox.grid(row=current_row, column=index * 2 + 1, padx=(0, padx), pady=pady) if field_tooltips: CreateTooltip(field_combobox, field_tooltips[index]) self.field_vars.append(field_var) self.field_widgets.append(field_combobox)
[docs] def get_values(self): """ Returns the current values of every field in this row, as a list of ints. Example: [1, 1, 1] for a unit cell growth row, or [1, 0, 0] for a Miller plane row. """ return [int(field_var.get()) for field_var in self.field_vars]
[docs] def set_values(self, values): """ Sets the current values of every field in this row. :param values: A list of ints, one per field, in the same order as input_label_list. """ for field_var, value in zip(self.field_vars, values): field_var.set(str(value))
[docs] def destroy(self): """Removes this row's widgets from the screen.""" self.frame.destroy()