13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【MATLAB】AppDesignerでGUIを作成する

Last updated at Posted at 2020-04-08

はじめに

matlabは便利なツールではあるが,スクリプトを実行する場合には基本的にはコマンドウィンドウ(CUI)でコマンドを叩く必要があり,コンピュータ操作に不慣れな人には使いづらいことがある.今回はmatlabAppDesignerを使用してGUIを作成する.
なお,作成は私も初めてであるので,上手くいくかは分からない.

どういうものを作るか

【MATLAB】指定フォルダ内のファイルを検索して処理をする
にて作成した,

指定したフォルダとそのサブフォルダ内の全てのWAVファイルを検索し,一つ一つのファイルを開いて,時間波形を描いてPNGで保存する

という処理をGUIにて行えるようにする.

AppDesigner立ち上げ

000.png
ホームタブの「新規作成」から「アプリ」を選択する.

001.png
「App Designer スタートページ」が立ち上がるので,「新規作成」の「空のアプリ」を選択する.

002.png
GUIの作成画面が立ち上がる.

コンポーネントを配置する

003.png
「コンポーネント ライブラリ」から必要なコンポーネントを画面中央にドラッグアンドドロップする.

004.png
上図のように,
・編集フィールド(テキスト)
・ボタンを2個
・テキストエリア
配置した.

コンポーネント説明

005.png
各コンポーネントの説明は以下の通り.

①フォルダ名指定エディットボックス
ここに処理するフォルダのフルパスを入力する.

②フォルダ名指定ダイアログ立ち上げボタン
「参照」ボタンを押下すると,フォルダ選択ダイアログが立ち上がり,ここで選択したフォルダのフルパスが①のフォルダ名指定エディットボックスに入力される.

ユーザは①または②から処理するフォルダを指定することになる.

③処理実行ボタン
「処理実行」ボタンを押下すると,「フォルダ名指定エディットボックス」で指定されたフォルダを検索し,処理を行う.

④メッセージ表示テキストボックス
各メッセージを表示する.
例えば「フォルダ名指定エディットボックス」が空または存在しないパスを指定して「処理実行」ボタンを押下した場合に「フォルダが存在しません!」などのメッセージを表示する.

コンポーネント名称

009.png
各コンポーネントの名称がデフォルトだと「Button」「Button_2」など分かりづらいので,上のように変更した.

試しに実行

006.png
実行してみた.当然,中の動きはまだ何も記述していないので,ボタンを押しても何も起こらない.

コンポーネントの処理を記述する

各ボタンに対して,ボタンが押された場合の動きを記述していく.

「参照」ボタン

010.png
「設計ビュー」で「参照」ボタンを押下または右カラムの「コンポーネントブラウザー」から「app.DirectoryButton」を選択し,「コンポーネントブラウザー」下部の「コールバック」タブを選択する.「ButtonPushedFcn」のコンボボックスの▼を押して「ButtonPushed コールバックの追加」を選択する.

011.png
中央カラムの「コードビュー」に「DirectoryButtonPushed」関数が追加された.ここに「参照」ボタンが押下された時の処理を記述していく.

DirectoryButtonPushed

function DirectoryButtonPushed(app, event)
    rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
    % 「キャンセル」が押された場合
    if(rootDir==0)
        return
    end
    app.DirectoryEditField.Value = rootDir;
end

app.DirectoryEditField.Valueが「フォルダ名指定エディットボックス」の値である.

「処理実行」ボタン

「参照」ボタンと同様に,ButtonPushed コールバック(ExecuteButtonPushed)を追加する.
ExecuteButtonPushed内に処理を全部書くと行数が増えて大変なので,プライベート関数を追加して細かい処理はそっちに書く.

プライベート関数の追加

012.png
「エディター」→「関数」→「プライベート関数」を選択する.

013.png
「コードビュー」にfuncが追加される.funcを適当な名前(ここではgetWavFileFullPaths)に変更する.

今回は引数としてフォルダのパスを指定すると,そのフォルダとサブフォルダからWAVファイルを検索して,そのフルパスを返すgetWavFileFullPaths関数を作る.

getWavFileFullPaths
function wavFileFullPaths = getWavFileFullPaths(~, directoryFullPath)
    % カレントディレクトリをバッファ
    origDir = pwd;
    % カレントディレクトリを変更
    cd(directoryFullPath);
    % カレントディレクトリとサブディレクトリを検索
    fileList = dir('**/*.WAV');
    % カレントディレクトリを戻す
    cd(origDir);
    % fileListからフルパスを作成
    wavFileFullPaths = fullfile({fileList.folder}, {fileList.name});
end

なお,fullfileの使い方は過去の投稿記事でいただいたコメントを参考にさせていただいた.

同様に,プロセスバーの文字列を生成するgetWaitBarTextも作成する.

getWaitBarText
function waitBarText = getWaitBarText(~, n, total)
    waitBarText = sprintf('Please wait...[%d/%d]', n, total);
end

「処理実行」ボタン コールバック関数

ExecuteButtonPushed
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を用いた.

念のため再掲すると↓
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];と書くと,テキストエリアに文字を追加出来るようである.

実行

014.png
実行してみた.(上図,パスの一部にユーザ名などが入っていたので白塗りにした)
期待通りの動きとなっている.

まとめ

今回はmatlabAppDesignerを用いてGUIを作成した.
過去に作成したスクリプト(*.mファイル)を実行出来るので,移行もやりやすい.
また,コールバック関数など自分で記述する必要のある箇所以外は編集できないようにプロテクトがかかっており,不用意にいじってアプリを起動できなくしちゃうなどの事故が防げるのはとても良いと思った.

13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?