はじめに
matlab
は便利なツールではあるが,スクリプトを実行する場合には基本的にはコマンドウィンドウ(CUI)でコマンドを叩く必要があり,コンピュータ操作に不慣れな人には使いづらいことがある.今回はmatlab
のAppDesigner
を使用してGUIを作成する.
なお,作成は私も初めてであるので,上手くいくかは分からない.
どういうものを作るか
【MATLAB】指定フォルダ内のファイルを検索して処理をする
にて作成した,
指定したフォルダとそのサブフォルダ内の全てのWAVファイルを検索し,一つ一つのファイルを開いて,時間波形を描いてPNGで保存する
という処理をGUIにて行えるようにする.
AppDesigner立ち上げ
「App Designer スタートページ」が立ち上がるので,「新規作成」の「空のアプリ」を選択する.
コンポーネントを配置する
「コンポーネント ライブラリ」から必要なコンポーネントを画面中央にドラッグアンドドロップする.
上図のように,
・編集フィールド(テキスト)
・ボタンを2個
・テキストエリア
配置した.
コンポーネント説明
①フォルダ名指定エディットボックス
ここに処理するフォルダのフルパスを入力する.
②フォルダ名指定ダイアログ立ち上げボタン
「参照」ボタンを押下すると,フォルダ選択ダイアログが立ち上がり,ここで選択したフォルダのフルパスが①のフォルダ名指定エディットボックスに入力される.
ユーザは①または②から処理するフォルダを指定することになる.
③処理実行ボタン
「処理実行」ボタンを押下すると,「フォルダ名指定エディットボックス」で指定されたフォルダを検索し,処理を行う.
④メッセージ表示テキストボックス
各メッセージを表示する.
例えば「フォルダ名指定エディットボックス」が空または存在しないパスを指定して「処理実行」ボタンを押下した場合に「フォルダが存在しません!」などのメッセージを表示する.
コンポーネント名称
各コンポーネントの名称がデフォルトだと「Button」「Button_2」など分かりづらいので,上のように変更した.
試しに実行
実行してみた.当然,中の動きはまだ何も記述していないので,ボタンを押しても何も起こらない.
コンポーネントの処理を記述する
各ボタンに対して,ボタンが押された場合の動きを記述していく.
「参照」ボタン
「設計ビュー」で「参照」ボタンを押下または右カラムの「コンポーネントブラウザー」から「app.DirectoryButton」を選択し,「コンポーネントブラウザー」下部の「コールバック」タブを選択する.「ButtonPushedFcn」のコンボボックスの▼を押して「ButtonPushed コールバックの追加」を選択する.
中央カラムの「コードビュー」に「DirectoryButtonPushed」関数が追加された.ここに「参照」ボタンが押下された時の処理を記述していく.
function DirectoryButtonPushed(app, event)
rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
% 「キャンセル」が押された場合
if(rootDir==0)
return
end
app.DirectoryEditField.Value = rootDir;
end
app.DirectoryEditField.Value
が「フォルダ名指定エディットボックス」の値である.
「処理実行」ボタン
「参照」ボタンと同様に,ButtonPushed コールバック(ExecuteButtonPushed
)を追加する.
ExecuteButtonPushed
内に処理を全部書くと行数が増えて大変なので,プライベート関数を追加して細かい処理はそっちに書く.
プライベート関数の追加
「コードビュー」にfunc
が追加される.func
を適当な名前(ここではgetWavFileFullPaths
)に変更する.
今回は引数としてフォルダのパスを指定すると,そのフォルダとサブフォルダからWAVファイルを検索して,そのフルパスを返すgetWavFileFullPaths
関数を作る.
function wavFileFullPaths = getWavFileFullPaths(~, directoryFullPath)
% カレントディレクトリをバッファ
origDir = pwd;
% カレントディレクトリを変更
cd(directoryFullPath);
% カレントディレクトリとサブディレクトリを検索
fileList = dir('**/*.WAV');
% カレントディレクトリを戻す
cd(origDir);
% fileListからフルパスを作成
wavFileFullPaths = fullfile({fileList.folder}, {fileList.name});
end
なお,fullfile
の使い方は過去の投稿記事でいただいたコメントを参考にさせていただいた.
同様に,プロセスバーの文字列を生成するgetWaitBarText
も作成する.
function waitBarText = getWaitBarText(~, n, total)
waitBarText = sprintf('Please wait...[%d/%d]', n, total);
end
「処理実行」ボタン コールバック関数
function ExecuteButtonPushed(app, event)
% メッセージテキストエリアの中身をクリア
app.MessageTextArea.Value = '';
% エディットボックスの値をチェック
if(~isfolder(app.DirectoryEditField.Value))
app.MessageTextArea.Value = 'フォルダが指定されていません.処理を終了します.';
return
end
% WAVファイルのフルパスを取得
wavFileFullPaths = getWavFileFullPaths(app, app.DirectoryEditField.Value);
n = length(wavFileFullPaths);
% プロセスバーを表示
h = waitbar(0, getWaitBarText(app, 0, n));
app.MessageTextArea.Value = '処理を開始します.';
for each = struct('path', wavFileFullPaths, 'index', num2cell(1:n))
% メインの処理
sampleSaveGraph(each.path);
% プロセスバーを更新
waitbar(each.index/n, h, getWaitBarText(app, each.index, n));
% テキストエリアにメッセージを表示
s = sprintf('処理完了[%d/%d]:%s', each.index, n, each.path);
app.MessageTextArea.Value = [app.MessageTextArea.Value; s];
end
app.MessageTextArea.Value = [app.MessageTextArea.Value; '処理を全て完了しました.'];
% プロセスバーを閉じる
close(h);
end
WAVファイルのフルパスを引数に入れると時間波形をPNG保存する関数sampleSaveGraph
は過去記事で作成したsampleSaveGraph.m
を用いた.
念のため再掲すると↓
function sampleSaveGraph(fullpath)
% WAVを開く
[y, Fs] = audioread(fullpath);
% グラフを描く
N = length(y);
t = ((1:N)-1)/Fs;
h = figure('WindowState','minimized');
plot(t, y);
xlim([0, t(end)]);
ylim([-1, 1]);
[filepath ,name, ext] = fileparts(fullpath);
% グラフタイトルはWAVファイル名とする
title([name, ext], 'Interpreter', 'none');
xlabel('時間[秒]');
ylabel('振幅');
% 保存するファイルのフルパスを生成
filename = fullfile(filepath, [name, '.png']);
% ファイルを保存
saveas(h, filename);
close(h);
end
なお,メインのループ処理は過去の投稿記事でいただいたコメントを参考にさせていただいた.
app.TextArea.Value = [app.TextArea.Value; hogehoge];
と書くと,テキストエリアに文字を追加出来るようである.
実行
実行してみた.(上図,パスの一部にユーザ名などが入っていたので白塗りにした)
期待通りの動きとなっている.
まとめ
今回はmatlab
のAppDesigner
を用いてGUIを作成した.
過去に作成したスクリプト(*.mファイル)を実行出来るので,移行もやりやすい.
また,コールバック関数など自分で記述する必要のある箇所以外は編集できないようにプロテクトがかかっており,不用意にいじってアプリを起動できなくしちゃうなどの事故が防げるのはとても良いと思った.