目的
ヘッダーを右クリックするとポップアップを表示し、列ごとのフィルタを設定できるようにします。
仕様
- 非数値列: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章:操作性を高める