第6章:ヘッダー右クリックでフィルタ(Excel風ポップアップ)

python

目的

ヘッダーを右クリックするとポップアップを表示し、列ごとのフィルタを設定できるようにします。

仕様

  • 非数値列:Values(ユニーク値)タブでチェックボックス選択
  • 数値列:Values タブは非表示。Number Filter タブで <=, <, ==, >=, > と閾値を指定
  • OK でフィルタを保存し、全列に対して AND で適用
  • フィルタ中の列ヘッダーには [F] を表示

数値列判定(ヘルパー)

def _is_numeric_column(self, col: str) -> bool:
    idx = self.data_columns.index(col)
    saw = False
    for _, row in self.data_rows:
        v = row[idx] if idx < len(row) else ""
        if v == "":  # 空は無視
            continue
        try:
            float(v)
            saw = True
        except Exception:
            return False
    return saw

フィルタ適用(AND で束ねる)

def apply_filter(self):
    base_rows = self.data_rows
    if self.column_filters:
        rows1 = []
        for ln, r in base_rows:
            ok = True
            for col, cfg in self.column_filters.items():
                idx = self.data_columns.index(col)
                val = r[idx] if idx < len(r) else ""
                if "values" in cfg and cfg["values"] is not None:
                    if val not in cfg["values"]:
                        ok = False; break
                if ok and ("num_op" in cfg and cfg["num_op"] is not None):
                    try: x = float(val)
                    except Exception: ok = False; break
                    op, th = cfg["num_op"], cfg.get("num_val")
                    if th is None: ok = False; break
                    if op == "<=" and not (x <= th): ok = False; break
                    if op == "<"  and not (x <  th): ok = False; break
                    if op == "==" and not (x == th): ok = False; break
                    if op == ">=" and not (x >= th): ok = False; break
                    if op == ">"  and not (x >  th): ok = False; break
            if ok:
                rows1.append((ln, r))
    else:
        rows1 = list(base_rows)
    self.current_rows = rows1
    self._populate_trees(self.data_columns, self.current_rows)

前へ → 第5章
次へ → 第7章:操作性を高める

タイトルとURLをコピーしました