3

私はdicom画像と分光法のツールを書いていますが、作成している関数間で使用したい共有データがたくさんあります。私は自分で作成したGUIを持っており、さまざまなスライダーとボタンがdicomファイルからのこの共有データの多くを使用しています。

私はこれらすべての関数が共有する情報を格納するためにグローバル変数を使用してきました。現在、グローバルがたくさんあります。結合が増えるため、可能であればグローバル変数を避けるように教えられてきました。各関数のdicomファイルからデータを読み込む方が良いでしょうか?これは冗長なようです。オブジェクト指向のヘルプとしてMATLABを使用しますか?

4

5 に答える 5

6

アプリケーションのデータ構造を使用することをお勧めします。

アプリケーションデータは、アプリケーションによって定義され、通常はGUIアプリケーションまたはFigureウィンドウにアタッチされる構造として格納される重要なデータです。

アプリケーションデータ(appdata)を使用するには、setappdataandgetappdata関数を使用します。たとえば、GUIへのハンドルがとして保存されていると仮定するとhGUI、以下はアプリケーションデータにランダム行列を追加し、後でそれを取得します(MATLABドキュメントから削除)

% Save matrix for later
matrix = randn(35);
setappdata(hGUI, 'mydata', matrix);

% Do some stuff...

% Retrieve my matrix, this could be in a different file to `setappdata`
myMatrix = getappdata(hGUI, 'mydata');

hGUI基本的に任意のデータをアプリケーションデータに保存でき、 GUIアプリケーションを参照している限り、任意のソースファイルからデータを保存して取得できます。

于 2012-02-02T20:41:42.380 に答える
4

GUI使用していて、コントロールコールバック間でデータを共有したいとおっしゃっていたので、ネストされた関数を使用してコードを設計することをお勧めします。全体的なコードは次のようになります。

function dicomGUI

  %# Initialize your GUI here, linking the control callbacks to the
  %#   nested functions below:

  hLoad = uicontrol('Style', 'push', 'String', 'Load file', ...
                    'Callback', @load_file);
  ...

  %# Initialize the data variables for the DICOM files here:

  data = [];  %# Shared among nested functions
  ...

  %# Below are all the nested functions your controls will use:

  function load_file(hSource, event)
    data = ...;  %# Load the data here
  end
  ...

end

これにより、すべてのGUIコードを1つのmファイルに入れることができるだけでなく、コントロールコールバックが簡素化され、親関数のワークスペースで変数を簡単に共有できるようになりますdicomGUI。このアプローチの例は、GUIコントロール間でデータを共有するための他の提案とともに、このドキュメントページにあります:GUIのコールバック間でデータを共有します。

クリスが述べているように、これは大きくて複雑なGUIの非常に大きなmファイルになる可能性があります。このような場合にファイルサイズを小さくするには、各コールバックの本体を、共有データ変数を受け入れ、必要な作業を実行してから、変更されたデータを同じファイルに返す別のファイル内の関数を呼び出すことをお勧めします。共有変数。例えば:

function transform_callback(hSource, event)

  %# Apply some transform to the data:
  data = transform_data(data);

  %# If the above changes the GUI (disabling controls, changing a
  %#   display, etc.), then those changes should be made here.

end
于 2012-02-02T20:45:59.177 に答える
2

原則として、グローバルは悪いことです。通常、次のような2つの優れた方法があります。

  1. 最初にデータを読み込み、それを必要とする各関数に渡します。
  2. データを読み取り、それを必要とする各関数は、それを返す関数を呼び出します。

データのみを使用するのか、データを変更して使用するのかによっては、返品時にデータパッケージを更新する必要がある場合もあります。

これらのアイデアのいずれかがプロセスに役立つはずです。これにより、コードがはるかに読みやすくなり、何らかの間違いを犯す可能性が低くなります。

于 2012-02-02T20:34:20.193 に答える
2

MATLABのオブジェクト指向の性質により、別の可能性があります。独自のハンドルクラスを定義し、初期化フェーズで追加の引数として各コールバックに渡すことができます。

classdef Data<handle
    properties (Access=public)
        Val;
    end
end

function SimpleGui
    data = Data();

    hLoad = uicontrol('Style', 'push', 'String', 'Push me', ...
                      'Callback', {@callback data});
    data.Val = 5;
end

function callback(hSource, event, data)
    data.Val = data.Val+1;
    disp(data.Val);
end

さらに別のオプション:

また、guidata/ appdata(@Chrisによって説明されている)に関しては、次のように改善できます。

常に取得および設定するカプセル化コールバックを作成しますguidata

function CallbackWrapper(hObj,evt,func)
    data = guidata(hObj);
    data = func(hObj,evt,data);
    guidata(hObj,data);
end

これで、コールバックは次のように定義する必要があります(異なる署名に注意してください)。

function SimpleGui
    hSave = uicontrol('Style', 'push', 'String', 'Push me', ...
        'Callback', {@CallbackWrapper @myCallBack});
    data.x = 1;
    guidata(hSave,data);
end

function data = myCallBack(hObj,evt,data)
    data.x = data.x + 1;
    disp(data.x);
end
于 2012-02-07T21:28:56.423 に答える
0

MATLABの最新リリースのいずれかを使用している場合は、OOPS(オブジェクト指向プログラミングシステム)を利用する必要があります。

ソフトウェア設計の原則を順守し、健全なソフトウェア設計を設計することから始める必要があります。コードを書く前にこれを行う必要があります。ソフトウェアモデリングにはUMLを使用することをお勧めします。

于 2012-02-02T20:37:51.243 に答える