2

私は大きな GUI に取り組んでいます。その本質的な構造は非常に初歩的なものであり、相互接続された 2 つのコントロール (それぞれが他の値を更新する) に簡単に減らすことができます: スライダーと編集ボックスです。それらが共有する値は、プロットを作成するために使用されます。次のコードを実行すると、(スライドの移動またはボックスの編集によって) 値を 1 回だけ変更できることがわかります。2回目はエラーになります。主な質問は次のとおりです。代わりに GUIHANDLES をどのように使用すべきですか?

function GuiHandleShare1

handles.figure=figure;

handles.edit=uicontrol('Style','Edit',...
                       'Position',[5  5 50 20],...
                       'Callback',@edit_callback,...
                       'Tag','edit');
handles.slider=uicontrol('Style','Slider',...
                         'Position',[55 5 500 20],...
                         'Callback',@slider_callback,...
                         'Tag','slider');
handles.axes=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes');

function plotter
handles=guihandles;
plot(handles.axes,[0 1],[0 str2num(get(handles.edit,'String'))])

function edit_callback(h,eventdata)
handles=guihandles;
set(handles.slider,'Value',str2num(get(handles.edit,'String')));
plotter

function slider_callback(h,eventdata)
handles=guihandles;
set(handles.edit,'string',num2str(get(handles.slider,'Value')));
plotter

guihandles のコードを掘り下げて答えを見つけようとしましたが、guidata と同じように、getappdata、setappdata などのラッパーであり、そのソースは利用できません (Matlab R2008b)。

この種の GUI の他の解決策は既に知っています。 1- guihandles、guidata などを使用する代わりに、グローバル変数を使用します。2-ネストされた関数を使用します。

ネストされた関数は、メイン関数ワークスペースが静的ワークスペースになるため、私が取り組んでいる場合のオプションではありません。アプリケーションで変数を管理する必要があるため、これは私が望んでいるものではありません。グローバル変数を使用することになりました。ハンドルを必要とするすべての関数内でハンドルをグローバルとして宣言しましたが、正常に動作しています。これってデメリットありますか?つまり、グローバル変数を使用できるのであれば、なぜ Matlab は guihandles や guidata などのコマンドを思いついたのでしょうか?

4

2 に答える 2

3

guidata() と同じではなく、Figure 内の実際のハンドルのリストを提供する関数 guihandles() を誤解していると思います。実際、handles.axes の名前を handles.axes1 に変更してみてください。最初のコールバックで失敗することがわかります。

このコードは guidata() を使用してデータを保存および取得します (行末のコメント)。

function GuiHandleShare1

handles.figure=figure;

handles.edit=uicontrol('Style','Edit',...
                       'Position',[5  5 50 20],...
                       'Callback',@edit_callback,...
                       'Tag','edit');
handles.slider=uicontrol('Style','Slider',...
                         'Position',[55 5 500 20],...
                         'Callback',@slider_callback,...
                         'Tag','slider');
handles.axes1=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes');
guidata(handles.figure, handles); % save handles to GUIDATA

function plotter
handles=guidata(gcf); % retrieve handles from GUIDATA
plot(handles.axes1,[0 1],[0 str2num(get(handles.edit,'String'))])

function edit_callback(h,eventdata)
handles=guidata(gcf);
set(handles.slider,'Value',str2num(get(handles.edit,'String')));
plotter

function slider_callback(h,eventdata)
handles=guidata(gcf);
set(handles.edit,'string',num2str(get(handles.slider,'Value')));
plotter
于 2014-09-29T20:24:25.840 に答える
3

このプロパティ/値のペアを使用する必要があります。

'NextPlot' ,'ReplaceChildren'

そうしないと、GUI は最初のプロットの後に新しい図を作成し、最初の軸に関連付けられたタグは無効になります。実際に入力すると

get(handles.axes)

作成後、このプロパティが「replace」に設定されていることがわかります。これにより、子ではなく軸全体が置き換えられます。したがって、コードは次のようになります。

handles.axes=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes','NextPlot' ,'ReplaceChildren');

グローバル変数の回避策として、findobj を使用して軸を検出し、そこにプロットすることもできます。

function plotter

hAx = findobj('Type','axes')
handles=guihandles;
plot([0 1],[0 str2num(get(handles.edit,'String'))],'parent',hAx);

ただし、複数の軸がある場合はあまり便利ではありません。

私の知る限り、GUI のグローバル変数はコードの実装を容易にしますが、私が知っている 1 つの注意点は、GUI からスタンドアロン アプリケーションをデプロイする場合、コンパイル中に大量のエラーがスローされることです。それらを取り除きます。

とにかく、上記のコードを使用するとうまくいきます。それが役立つことを願っています!

于 2014-09-29T19:51:58.423 に答える