コンポーネント工房:Reflexライブラリ100
·
講座の概要
レイアウト
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
タイポグラフィ
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
フォーム
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
データ表示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
開閉と切り替え
·
Tabs
·
Accordion
·
Segmented Control
オーバーレイ
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
動的レンダリング
·
Cond
·
Match
·
Foreach
·
Auto Scroll
メディア
·
Image
·
Audio
·
Video
表とデータグリッド
·
Table
·
Data Table
·
Data Editor
チャート
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
チャートの部品
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
ほかのチャートライブラリ
·
Plotly
·
Pyplot
HTML要素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
そのほかの道具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
工房の注文書
カフェの在庫表をExcelのようにセルをクリックしてその場で直せるようにし、直すたびに在庫の総額が計算し直されるようにしてください。
rx.data_editorは、スプレッドシートのようにセルを選んで編集できるデータグリッドです。Glide Data Gridで描画するので、行や列がとても多くても高速です。読むだけの表ならData Tableで十分で、ユーザーに値を編集させたいときにこのコンポーネントを使います。
columnsは、列ごとに1つのdictを並べたリストです。
title:列見出しです。id:列のidです。省略するとtitleを小文字にした値になります。width:列幅(px)です。type:セルの種類です。"str"(既定)、"int"、"float"、"bool"、"image"を使います。group:同じ値を持つ列の上に、まとめの見出しをもう1段描きます。dataは、行ごとに1つのリストを並べたリストです。各値はその列のtypeと合っている必要があります。
rx.data_editor(
columns=[
{"title": "Code", "type": "str"},
{"title": "Value", "type": "int"},
{"title": "Activated", "type": "bool"},
],
data=[
["A", 1, True],
["B", 2, False],
["C", 3, False],
["D", 4, True],
["E", 5, True],
["F", 6, False],
],
)グリッドをクリックして、セル、行、列を選んでみてください。セルをダブルクリックすると編集ウィンドウが開きます(この実習台では値を保存しないので、直した値はすぐ元に戻ります)。
プロパティを変えてみる
row_markers
column_select
row_select
range_select
vertical_border
show_search
rx.data_editor(
columns=[
{"title": "Code", "type": "str"},
{"title": "Value", "type": "int"},
{"title": "Activated", "type": "bool"},
],
data=[["A", 1, True], ["B", 2, False], ["C", 3, False], ["D", 4, True]],
row_markers="number",
column_select="single",
row_select="multi",
range_select="rect",
vertical_border=True,
show_search=False,
height="220px",
)| プロパティ | 値 | 用途 |
|---|---|---|
columns · data | リスト | 列の設定、行のデータ |
rows | 整数 | 行数。省略するとdataの長さ |
row_height · header_height · group_header_height | 整数(px) | 行、列見出し、まとめ見出しの高さ |
row_markers | "none" "number" "checkbox" "both" "checkbox-visible" "clickable-number" | 行頭の表示 |
row_marker_start_index · row_marker_width | 整数 | 行番号の開始値、表示欄の幅 |
freeze_columns | 整数 | 横スクロール時に左側へ固定する列の数 |
min_column_width · max_column_width · max_column_auto_width | 整数(px) | 列幅の上限・下限 |
column_select · row_select | "none" "single" "multi" | 列・行の選択 |
range_select | "none" "cell" "rect" "multi-cell" "multi-rect" | セル範囲の選択 |
*_selection_blending · row_selection_mode · span_range_behavior | 文字列 | 複数種類の選択を併用するかなど、細かな動作 |
smooth_scroll_x · smooth_scroll_y | True / False | なめらかなスクロール |
vertical_border · draw_focus_ring · fixed_shadow_x · fixed_shadow_y | True / False | 縦の罫線、フォーカス枠、固定領域の影 |
fill_handle | True / False | セルの角をドラッグして値を埋めるハンドル |
get_cells_for_selection | True / False | 選んだセルをコピーできるようにする(既定はTrue) |
overscroll_x · overscroll_y · scroll_offset_x · scroll_offset_y | 整数 | 端を越えたスクロールの余裕、最初のスクロール位置 |
prevent_diagonal_scrolling · show_search | True / False | 斜めスクロールを防ぐ、検索ボックス |
theme | rx.data_editor_theme(...)またはdict | 色とフォント |
grid_selection | 選択のdict | 現在の選択。on_grid_selection_changeを使うなら必ず一緒につなぐ |
| イベント | 受け取る値 | タイミング |
|---|---|---|
on_cell_clicked · on_cell_activated · on_cell_context_menu | [列, 行] | セルをクリックしたとき、Enter・ダブルクリックでアクティブにしたとき、右クリックしたとき |
on_cell_edited | [列, 行]、新しいセルのdict | セルの値を編集したとき(新しい値はdict["data"]) |
on_finished_editing | 新しいセルのdict、移動方向 | 編集ウィンドウが閉じたとき |
on_header_clicked · on_header_context_menu | [列, 行] | 列見出しをクリックしたとき、右クリックしたとき |
on_header_menu_click | 列、位置 | 列見出しのメニューボタンを押したとき |
on_group_header_clicked · on_group_header_context_menu · on_group_header_renamed | - | まとめ見出しをクリックしたとき、右クリックしたとき、名前を変えたとき |
on_item_hovered | [列, 行] | マウスがセルの上に乗ったとき |
on_grid_selection_change · on_selection_cleared | 選択のdict · - | 選択が変わったとき、解除されたとき |
on_delete | 選択のdict | 選んだセルでDeleteキーを押したとき |
on_row_appended · on_column_resize · on_search_close | - · 列、幅 · - | 行の追加、列幅の調整、検索ボックスを閉じたとき |
type="image"の列は、画像のURLを小さな画像として表示します。値はURL 1つでも、複数の画像を入れたURLのリストでもかまいません。画像がよく見えるようrow_heightを大きくします。画像セルをクリックすると、拡大表示のウィンドウが開きます。
rx.data_editor(
columns=[
{"title": "Preview", "type": "image", "width": 120},
{"title": "Name", "type": "str"},
],
data=[
["https://picsum.photos/id/237/160/100", "Puppy"],
["https://picsum.photos/id/1025/160/100", "Pug"],
[["https://picsum.photos/id/1084/160/100", "https://picsum.photos/id/1074/160/100"], "Two animals"],
],
row_height=90,
height="320px",
)on_cell_clickedは、クリックしたセルの位置を[列, 行]で渡します(どちらも0から数えます)。下の列設定にはgroup: "Data"があるので、Titleを除く5列の上に「Data」というまとめ見出しがもう1段できます。
from typing import Any
class DataEditorClickState(rx.State):
clicked_data: str = "Cell clicked: "
cols: list[dict[str, Any]] = [
{"title": "Title", "type": "str"},
{"title": "Name", "type": "str", "group": "Data", "width": 220},
{"title": "Birth", "type": "str", "group": "Data", "width": 150},
{"title": "Human", "type": "bool", "group": "Data", "width": 80},
{"title": "House", "type": "str", "group": "Data"},
{"title": "Patronus", "type": "str", "group": "Data"},
]
data: list[list[Any]] = [
["1", "Harry James Potter", "31 July 1980", True, "Gryffindor", "Stag"],
["2", "Ronald Bilius Weasley", "1 March 1980", True, "Gryffindor", "Jack Russell terrier"],
["3", "Hermione Jean Granger", "19 September 1979", True, "Gryffindor", "Otter"],
["4", "Rubeus Hagrid", "6 December 1928", False, "Gryffindor", "None"],
]
@rx.event
def click_cell(self, pos: tuple[int, int]):
col, row = pos
self.clicked_data = f"Cell clicked: column {col}, row {row}"
rx.vstack(
rx.heading(DataEditorClickState.clicked_data, size="3"),
rx.data_editor(
columns=DataEditorClickState.cols,
data=DataEditorClickState.data,
on_cell_clicked=DataEditorClickState.click_cell,
height="220px",
),
width="100%",
)Data Editorはセルを編集できるようにするだけで、編集した値を自動では保存しません。on_cell_editedハンドラーが位置と新しいセルの情報を受け取り、Stateのdataを書き換えてはじめて画面に残ります。新しい値はnew_value["data"]にあります。セルをダブルクリックして値を直すか、Activatedのチェックボックスを押してみてください。
公式ドキュメントにはこのイベントの例が載っていませんが、編集できるグリッドを作るには欠かせません。
Last edit: nothing yet
from typing import Any
class DataEditorEditState(rx.State):
cols: list[dict[str, Any]] = [
{"title": "Code", "type": "str"},
{"title": "Value", "type": "int"},
{"title": "Activated", "type": "bool"},
]
data: list[list[Any]] = [["A", 1, True], ["B", 2, False], ["C", 3, False]]
last_edit: str = "nothing yet"
@rx.event
def edit_cell(self, pos: tuple[int, int], new_value: dict[str, Any]):
col, row = pos
rows = [list(r) for r in self.data]
rows[row][col] = new_value.get("data")
self.data = rows
self.last_edit = f"row {row}, column {col} -> {new_value.get('data')}"
@rx.event
def add_row(self):
self.data = self.data + [["New", 0, False]]
rx.vstack(
rx.data_editor(
columns=DataEditorEditState.cols,
data=DataEditorEditState.data,
on_cell_edited=DataEditorEditState.edit_cell,
row_markers="number",
height="200px",
),
rx.hstack(
rx.button("Add row", size="1", on_click=DataEditorEditState.add_row),
rx.text("Last edit: ", DataEditorEditState.last_edit, size="2"),
align="center",
),
width="100%",
)themeに色とフォントを渡します。rx.data_editor_theme(...)(公式ドキュメントではfrom reflex.components.datadisplay.dataeditor import DataEditorTheme)にキーワード引数を渡すか、dictをそのまま渡します。キーはaccent_colorのようなスネークケースでも、accentColorのようなキャメルケースでもかまいません。下はダークテーマにrow_height=50、なめらかなスクロール、1列ずつの選択を加えたものです。
dataeditor_dark_theme = {
"accent_color": "#8c96ff",
"accent_light": "rgba(202, 206, 255, 0.253)",
"text_dark": "#ffffff",
"text_medium": "#b8b8b8",
"text_light": "#a0a0a0",
"text_bubble": "#ffffff",
"bg_icon_header": "#b8b8b8",
"fg_icon_header": "#000000",
"text_header": "#a1a1a1",
"text_header_selected": "#000000",
"bg_cell": "#16161b",
"bg_cell_medium": "#202027",
"bg_header": "#212121",
"bg_header_has_focus": "#474747",
"bg_header_hovered": "#404040",
"bg_bubble": "#212121",
"bg_bubble_selected": "#000000",
"bg_search_result": "#423c24",
"border_color": "rgba(225,225,225,0.2)",
"drilldown_border": "rgba(225,225,225,0.4)",
"link_color": "#4F5DFF",
"header_font_style": "bold 14px",
"base_font_style": "13px",
}
rx.data_editor(
columns=[
{"title": "Code", "type": "str", "width": 120},
{"title": "Value", "type": "int", "width": 120},
{"title": "Activated", "type": "bool", "width": 120},
],
data=[["A", 1, True], ["B", 2, False], ["C", 3, False], ["D", 4, True], ["E", 5, True]],
row_height=50,
smooth_scroll_x=True,
smooth_scroll_y=True,
column_select="single",
theme=rx.data_editor_theme(**dataeditor_dark_theme),
height="260px",
)在庫表をon_cell_editedで保存し、在庫の総額と再注文の数を計算変数で作ります。数量や単価を直すと、下のバッジがすぐに変わります。品目の列はfreeze_columns=1で固定します。
from typing import Any
class DataEditorStockState(rx.State):
cols: list[dict[str, Any]] = [
{"title": "Item", "type": "str", "width": 160},
{"title": "Qty", "type": "int", "width": 80},
{"title": "Unit price", "type": "float", "width": 110},
{"title": "Reorder", "type": "bool", "width": 90},
]
data: list[list[Any]] = [
["Coffee beans", 12, 18.5, False],
["Paper cups", 300, 0.1, False],
["Oat milk", 4, 2.9, True],
]
@rx.event
def edit_cell(self, pos: tuple[int, int], new_value: dict[str, Any]):
col, row = pos
rows = [list(r) for r in self.data]
rows[row][col] = new_value.get("data")
self.data = rows
@rx.var
def total(self) -> str:
value = sum(float(r[1] or 0) * float(r[2] or 0) for r in self.data)
return f"${value:,.2f}"
@rx.var
def reorder_count(self) -> int:
return sum(1 for r in self.data if r[3])
rx.vstack(
rx.data_editor(
columns=DataEditorStockState.cols,
data=DataEditorStockState.data,
on_cell_edited=DataEditorStockState.edit_cell,
row_markers="number",
freeze_columns=1,
height="180px",
),
rx.hstack(
rx.badge("Stock value: ", DataEditorStockState.total, size="2"),
rx.badge("To reorder: ", DataEditorStockState.reorder_count, color_scheme="orange", size="2"),
),
width="100%",
)工房ノート
columnsは{title, type, width, id, group}のdictのリスト、dataは行のリスト。値は列のtypeに合わせる。
type:str · int · float · bool · image。
編集した値は、on_cell_edited((列, 行), 新しいセル)でStateのdataを書き換えないと残らない。
選択範囲はcolumn_select · row_select · range_select、行頭の表示はrow_markers。
theme=rx.data_editor_theme(...)またはdict、大きさはheightとrow_heightで決める。
新しい授業・講座のお知らせを受け取る
この講座に授業が追加されたり、続きの講座が公開されたりしたらメールでお知らせします。
R
ReflexKR
触って学ぶPythonとReflex。すべての例はReflex 0.10.0で実際に動かして確認しています。
ReflexKRはバナー広告なし・無料で運営しています。役に立ったら、コーヒー一杯で応援してください。 ☕ コーヒーで応援する
アフィリエイトと支援について© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
質問と回答
この回について気になることを書き込んでください。すべての言語のページの質問がここに集まります。