コールバック間のデータ共有
アプリの UI コンポーネントのコールバック関数を記述して、ユーザーが操作するときの動作を指定できます (アプリのコールバック関数の詳細については、プログラムで作成したアプリ用のコールバックの作成を参照してください)。
相互に依存する複数の UI コンポーネントをもつアプリでは、コールバック関数からメインのアプリ関数内で定義されたデータにアクセスしたり、他のコールバックとデータを共有したりしなければならないことがよくあります。たとえば、リスト ボックスをもつアプリを作成する場合、アプリ ユーザーが選択したリスト ボックスのオプションに基づいてアプリのイメージを更新することがあります。各コールバック関数はそれぞれ固有のスコープをもつため、この関数にアクセスする必要があるアプリの各部分でリスト ボックスのオプションとイメージに関する情報を明示的に共有しなければなりません。そのためには、メインのアプリ関数を使用して、その情報をコールバックと共有できる方法で格納します。その後、コールバック関数内から情報にアクセスしたり情報を変更したりします。
アプリ データの格納
アプリの UI コンポーネントのプロパティには、役立つ情報が含まれています。たとえば、Value
プロパティをクエリすると、スライダーの現在の位置がわかります。UI コンポーネントを作成する際は、プロパティの設定とアクセスをアプリ コード全体から行えるように、コンポーネントを変数として格納します。
事前定義されるプロパティのほかに、すべてのコンポーネントに UserData
プロパティがあり、これを使用して任意の MATLAB® データを格納できます。UserData
で一度に保持できる変数は 1 つのみですが、複数の値を構造体配列または cell 配列として格納できます。UserData
を使用して、アプリの UI コンポーネントへのハンドルのほか、アプリ コード内から更新が必要になる可能性がある他のアプリ データも格納できます。1 つの方法として、メイン アプリの Figure ウィンドウの UserData
プロパティにすべてのアプリ データを格納すると便利です。アプリのいずれかのコンポーネントにアクセスできれば、関数 ancestor
を使用してメインの Figure ウィンドウにアクセスできます。そのため、各コンポーネントのコールバック内からアクセスできる場所にすべてのアプリ データが保持されることになります。
たとえば、次のコードは日付ピッカー コンポーネントをもつ Figure を作成します。Figure の UserData
プロパティに、日付ピッカーと今日の日付の両方を構造体配列として格納します。
fig = uifigure; d = uidatepicker(fig); date = datetime("today"); fig.UserData = struct("Datepicker",d,"Today",date);
メモ
UserData
プロパティは、アプリのユーザー インターフェイスに直接関連するデータの格納にのみ使用します。大規模なデータ セットやアプリ コード内で作成または変更されるデータ以外をアプリで使用する場合は、代わりにこのデータを別のファイルに格納し、そのファイルにアプリ内からアクセスします。
シンプルなアプリケーションの場合は、アプリ データを UserData
プロパティに格納する代わりに、メインのアプリ関数に変数として格納し、各コールバックに入力引数または入れ子関数を使用して関連データを提供します。
コールバック関数からのアプリ データへのアクセス
コンポーネントのコールバック関数でアプリ データにアクセスするには、次のいずれかの方法を使用します。
UserData のデータへのアクセス — この方法は、コールバック関数内からアプリ データを更新する場合に使用します。前のセクションの説明に従って、アプリ データを
UserData
プロパティに格納しておく必要があります。コールバックへの入力データの引き渡し — この方法は、シンプルなアプリで、コールバックがアクセスできるデータを制限する場合に使用します。コールバック コードを簡単に再利用できるようになります。
入れ子にされたコールバック関数の作成 — この方法は、シンプルなアプリで、コールバック関数にすべてのアプリ データへのアクセスを提供する場合に使用します。アプリ コードを単一のファイルにまとめることができます。
以降の各セクションで、これらの方法について 1 つずつ説明し、各方法を使用してアプリ内でデータを共有する例を示します。各例の最終的なアプリの動作は同じで、アプリ ユーザーがテキスト エリアにテキストを入力し、ボタンをクリックしてテキストからワード クラウドを生成できるようにします。そのためには、アプリのテキスト エリア、ボタン、およびワード クラウドを保持するパネルでデータを共有する必要があります。このデータをそれぞれ異なる方法で共有する例を示します。
UserData
のデータへのアクセス
すべてのアプリ データを 1 か所にまとめておくには、すべてのコンポーネントから簡単にアクセスできる場所にデータを格納します。最初に、アプリ コードのセットアップ部分で、Figure ウィンドウの UserData
プロパティを使用して、コンポーネントがコールバックからアクセスする必要があるすべてのデータを格納します。各 UI コンポーネントはメインの Figure の子であるため、コールバック関数内から関数 ancestor
を使用して Figure にアクセスできます。たとえば、btn
という名前の変数で格納されたボタンをもつパネルが Figure に含まれている場合、次のコードを使用して Figure にアクセスできます。
fig = ancestor(btn,"figure","toplevel");
UserData
に格納されたアプリ データにアクセスして変更できます。例: UserData
を使用したワード クラウド アプリ
ワード クラウド アプリで、アプリ ユーザーがボタンをクリックしたときにアプリ データを共有するには、Figure の UserData
プロパティにデータを格納します。テキスト エリアのテキストに基づいてワード クラウドをプロットする createWordCloud
という名前の ButtonPushedFcn
コールバック関数を定義します。関数 createWordCloud
は、ボタンがクリックされたときにテキスト ボックスの値にアクセスできる必要があります。また、データをプロットするパネル コンテナーにもアクセスできる必要があります。このアクセスを提供するには、Figure の UserData
をテキスト エリア コンポーネントとパネル コンテナーを格納する struct
に設定します。
fig.UserData = struct("TextArea",txt,"Panel",pnl);
関数 createWordCloud
で、Figure の UserData
プロパティにアクセスします。MATLAB により、コールバックを実行するコンポーネントがコールバック関数に src
として自動的に渡されるため、コールバック関数内から関数 ancestor
を使用して Figure にアクセスできます。
fig = ancestor(src,"figure","toplevel");
その後、Figure を使用してパネルとテキストにアクセスできます。
data = fig.UserData; txt = data.TextArea; pnl = data.Panel; val = txt.Value;
この例を実行するには、関数 shareUserData
を MATLAB パス上の shareUserData.m
という名前のファイルに保存します。
function shareUserData % Create figure and grid layout fig = uifigure; gl = uigridlayout(fig,[2,2]); gl.RowHeight = {'1x',30}; gl.ColumnWidth = {'1x','2x'}; % Create and lay out text area txt = uitextarea(gl); txt.Layout.Row = 1; txt.Layout.Column = 1; % Create and lay out button btn = uibutton(gl); btn.Layout.Row = 2; btn.Layout.Column = 1; btn.Text = "Create Word Cloud"; % Create and lay out panel pnl = uipanel(gl); pnl.Layout.Row = [1 2]; pnl.Layout.Column = 2; % Store data in figure fig.UserData = struct("TextArea",txt,"Panel",pnl); % Assign button callback function btn.ButtonPushedFcn = @createWordCloud; end % Process and plot text function createWordCloud(src,event) fig = ancestor(src,"figure","toplevel"); data = fig.UserData; txt = data.TextArea; pnl = data.Panel; val = txt.Value; words = {}; for k = 1:length(val) text = strsplit(val{k}); words = [words text]; end c = categorical(words); wordcloud(pnl,c); end
コールバックへの入力データの引き渡し
コールバック関数からデータにアクセスする必要がある場合、そのデータをコールバックに入力として直接渡すことができます。MATLAB によってすべてのコールバック関数に入力として自動的に渡される src
と event
に加え、追加の入力引数をコールバック関数で宣言できます。それらの入力引数を cell 配列または無名関数を使用してコールバック関数に渡します。
例: コールバックの入力引数を使用したワード クラウド アプリ
ワード クラウド アプリで、アプリ ユーザーがボタンを押したときにアプリ データを共有するには、そのデータを ButtonPushedFcn
コールバック関数に渡します。
テキスト エリアのテキストに基づいてワード クラウドをプロットする createWordCloud
という名前の ButtonPushedFcn
コールバック関数を定義します。関数 createWordCloud
は、ボタンがクリックされたときにテキスト ボックスの値にアクセスできる必要があります。また、データをプロットするパネル コンテナーにもアクセスできる必要があります。このアクセスを提供するには、必須の引数である src
と event
に加え、テキスト エリアとパネルを入力引数として取るように createWordCloud
を定義します。
function createWordCloud(src,event,txt,pnl) % Code to plot the word cloud end
createWordCloud
コールバック関数を割り当て、createWordCloud
へのハンドルの後に追加の入力引数を含む cell 配列として ButtonPushedFcn
を指定してテキスト エリアとパネルを渡します。
btn.ButtonPushedFcn = {@createWordCloud,txt,pnl};
この例を実行するには、関数 shareAsInput
を MATLAB パス上の shareAsInput.m
という名前のファイルに保存します。
function shareAsInput % Create figure and grid layout fig = uifigure; gl = uigridlayout(fig,[2,2]); gl.RowHeight = {'1x',30}; gl.ColumnWidth = {'1x','2x'}; % Create and lay out text area txt = uitextarea(gl); txt.Layout.Row = 1; txt.Layout.Column = 1; % Create and lay out button btn = uibutton(gl); btn.Layout.Row = 2; btn.Layout.Column = 1; btn.Text = "Create Word Cloud"; % Create and lay out panel pnl = uipanel(gl); pnl.Layout.Row = [1 2]; pnl.Layout.Column = 2; % Assign button callback function btn.ButtonPushedFcn = {@createWordCloud,txt,pnl}; end % Process and plot text function createWordCloud(src,event,txt,pnl) val = txt.Value; words = {}; for k = 1:length(val) text = strsplit(val{k}); words = [words text]; end c = categorical(words); wordcloud(pnl,c); end
入れ子にされたコールバック関数の作成
最後に、コールバック関数をプログラム アプリのメイン関数内で入れ子にできます。こうすると、入れ子にされたコールバック関数はメイン関数とワークスペースを共有します。その結果、入れ子関数はメイン関数に定義されているすべての UI コンポーネントと変数にアクセスできるようになります。
例: 入れ子にされたコールバックを使用したワード クラウド アプリ
ワード クラウド アプリで、アプリ ユーザーがボタンを押したときにアプリ データを共有するには、ボタンのコールバック関数をメインのアプリ関数内に入れ子にします。テキスト エリアのテキストに基づいてワード クラウドをプロットする createWordCloud
という名前の ButtonPushedFcn
コールバック関数を定義します。関数 createWordCloud
は、ボタンがクリックされたときにテキスト ボックスの値にアクセスできる必要があります。また、データをプロットするパネル コンテナーにもアクセスできる必要があります。このアクセスを提供するには、メイン関数の nestCallback
内で createWordCloud
を定義します。この入れ子関数は、テキスト エリアとパネルのコンポーネントを格納する変数 t
と p
にアクセスできます。
この例を実行するには、関数 nestCallback
を nestCallback.m
という名前のファイルに保存して実行します。
function nestCallback % Create figure and grid layout fig = uifigure; gl = uigridlayout(fig,[2,2]); gl.RowHeight = {'1x',30}; gl.ColumnWidth = {'1x','2x'}; % Create and lay out text area t = uitextarea(gl); t.Layout.Row = 1; t.Layout.Column = 1; % Create and lay out button b = uibutton(gl); b.Layout.Row = 2; b.Layout.Column = 1; b.Text = "Create Word Cloud"; % Create and lay out panel p = uipanel(gl); p.Layout.Row = [1 2]; p.Layout.Column = 2; % Assign button callback function b.ButtonPushedFcn = @createWordCloud; % Process and plot text function createWordCloud(src,event) val = t.Value; words = {}; for k = 1:length(val) text = strsplit(val{k}); words = [words text]; end c = categorical(words); wordcloud(p,c); end end