7

ユーザー インターフェイスについては、uitable. ユーザーは最初の列でオプションA、B、または Cを選択し、2 番目の列のサブオプションは、最初の列で選択されたもの ( A.1、A.2、A.3、またはB.1、B.2)によって異なります。またはB.3またはCについても同じ

ここに画像の説明を入力

表のコードは、付録 Aにあります。

ユーザーが最初にメイン オプションを定義すると、それに応じてサブオプションが自動的に削減され、有効な選択肢のみが表示されます。CellEditCallbackこれは、列 1 の を評価し、列 2 の をリセットすることによって実現されます。 (付録 BColumnFormat関数) ユーザーが間違いに気づき、サブオプションをもう一度編集する必要がある場合でも、 は以前に編集されたものに従って設定されます。メインオプションと有効な選択肢は、もう一度メインオプションを選択しない限り利用できません。(写真の青い強調表示を参照してください)。modifySelectionColumnFormat

これを解決するためにCellSelectionCallback、関数の呼び出しも実装しましたjustifySelection(付録 Bにあります)。これは、列 1 でどのオプションが選択されたかを選択してチェックし、列 2 に適切なサブオプションを再度提供します。しかし、このコールバックは選択に反応するため、を2 回選択するには、1 回は をトリガーしCellSelectionCallback、もう 1 回は実際に選択を取得します。大きなテーブルの場合、これは非常に煩わしい場合があります。

だから私の質問は:

対応する列 1 の内容がわかるまで、列 2 のポップアップ メニューがポップアップしないようにして、有効な選択肢をすぐに提供する方法はありますか?

または:

セルのマウス クリックを検出して、行と列のインデックスを取得するにはどうすればよいですか? しかし、次の選択を呼び出してアクションをポップアップすることなく?

私はすでに利用可能なすべてのプロパティをかき集めていましたが、役立つ可能性のあるものは何も見つかりませんでした. を使用して何かを実行できるかもしれませんButtonDownFcnが、セル インデックスを取得するにはどうすればよいでしょうか。プロパティはどうですかBusyAction、それを私の目的にどのように使用できますか?

何か案は?

非常に多くのコードであなたを爆撃する前に申し訳ありません.これはすでに最も最小限の例ですが、完全に実行可能であるため、試してみることができます.


付録 A/B

function fancyUitable 

selector_1 = { 'A'; 'B' ; 'C' };
selector_2 = { 'first select first row!' };

h = figure('Position',[200 100 268 120],'numbertitle','off','MenuBar','none');

defaultData =  repmat( {'select main option...', 'select suboption...'} ,5,1);
columnname =   {'Option                             ',...
                'Suboption                          '};
columnformat = { {selector_1{:}}, selector_2 };
columneditable =  [true true]; 
t = uitable(h,'Units','normalized','Position',[0 0 1 1],...
              'Data', defaultData,... 
              'ColumnName', columnname,...
              'ColumnEditable', columneditable,...
              'ColumnFormat', columnformat,...  
              'RowName',[],...
              'CellEditCallback',@modifySelection,...
              'CellSelectionCallback',@justifySelection);

set(h,'Tag','Config_figure')
set(t,'Tag','Config_table')
end

%   **Appendix B**
%   (part of the same function file)


function modifySelection(~,evt_edit)
if evt_edit.Indices(2) == 1
    modifyPopup( evt_edit.Indices(1) );
end
end

function justifySelection(~,evt_select)
try  %to surpress an unimportant error
    if evt_select.Indices(2) == 2
        modifyPopup( evt_select.Indices(1) );
    end
end
end

modifyPopup最後に、以下を書き換える単一の関数Columnformat:

function  modifyPopup( row )
    id_group_1 = {'A.1';'A.2';'A.3'};
    id_group_2 = {'B.1';'B.2';'B.3'};
    id_group_3 = {'C.1';'C.2';'C.3'};
    id_default = {'select main option first'};

    myfigure = findobj('Tag','Config_figure');
    config_data = get(findobj(myfigure,'Tag','Config_table'),'Data');
    selector = config_data(row,1);
    selector = selector{1};

    config_format = get(findobj(myfigure,'Tag','Config_table'),'ColumnFormat');
    switch selector
        case 'A'
            config_format{2} = id_group_1';
        case 'B'
            config_format{2} = id_group_2';
        case 'C'
            config_format{2} = id_group_3';
        otherwise
            config_format{2} = id_default;
    end
    set(findobj(myfigure,'Tag','Config_table'),'ColumnFormat',config_format)
end

バウンティ: なぜ +50 なのですか? - 最初の正しいアイデアがあれば、それは不可能か、答えは簡単だと思います。Java オブジェクトのプロパティなどを使用した複雑な回避策を探しているわけではありません。よろしくお願いします。


概要を維持するために、ここにコメントからの議論を含めます。

試してみたい場合は、コードをコピーし、次の手順に従って望ましくない動作を再現できます。

  1. 最初の行でメイン オプション A を選択します。
  2. 最初の行のサブオプションには、選択肢 A.1、A.2、および A.3 が含まれます。
  3. 2 行目のメイン オプション B を選択すると、2 行目のサブオプションの選択肢は B.1、B.2、および B.3 になります。
  4. しかし今、最初の行のサブオプションを (直接) 変更したいと考えています。A.1、A.2、および A.3 の選択肢が得られると予想されます。しかし、あなたはしません。B.1、B.2、および B.3 が提供されます。- 最後に選択した主なオプションが B だったからです (行は異なりますが)。

最後のオプションを探すのではなく、関連するオプションを見る必要があるようです。したがって、サブオプションをクリックすると「ルックアップ」が実行され、どのメイン オプションがあるかが確認されます。

それはまさに私が探しているものです! しかし、どうすればそれができますか?クリックを検出し、列と行のインデックスを取得し、右に設定して ColumnFormat、最後にセルをポップアップさせる方法。これまでに見た唯一の可能性は ですがCellSelectionCallback、セルが無効な選択肢ですでにポップアップした後に実行されます。のようなものが必要ClickedCallbackですpushbuttons

または、メイン オプションを選択すると、その行のサブオプションのみが設定されるようにします。

それは不可能です。変更する必要があるため、特定の行にサブオプションを設定することはできませんColumnFormat。これは、1 つの行だけでなくテーブル全体に影響します。

4

3 に答える 3

4

私は Rody Oldenhuis の努力と解決策に非常に感謝しており、彼は間違いなく賞に値するものでしたが、彼の解決策は私のコードに多くの変更を加える必要があったため、より単純な解決策を探し続けました。これで、ついに 99% バグフリーになりました。

(関数スクリプト内のすべてのコード部分)

function fancyUitable 

close all

%basic properties
line_height = 21.32;
table_height = 6*line_height;
lh = line_height/table_height;
cw = 200; %columnwidth

h = figure('Position',[200 100 2*cw+2 table_height],...
           'numbertitle','off','MenuBar','none');

%header
uitable(h,'Units','normalized','Position',[0 1-lh 1 lh],...
              'ColumnWidth', {cw cw},...              
              'ColumnName', {'Option','Suboption'},...
              'RowName',[]);

%button (currently no icon) to store table
tbar = uitoolbar(h);
uipushtool(tbar,'ClickedCallback',@store);

% addrow(figurehandle,number of row, percentage lineheight)
% every function call creates a new row, later dynamically
addRow(h,1,lh);
addRow(h,2,lh);
addRow(h,3,lh);
addRow(h,4,lh);
addRow(h,5,lh);
end

function edit(src,evt)

if evt.Indices(2) == 1
    modifyPopup( src,evt.Indices(1) );
end

% disables cell selection highlighting, when one jumps to next table,
% a bit laggy though
fh = get(src,'parent');
copyobj(src,fh);
delete(src);

end

function  modifyPopup( src,row )
    id_group_1 = {'A.1';'A.2';'A.3'};
    id_group_2 = {'B.1';'B.2';'B.3'};
    id_group_3 = {'C.1';'C.2';'C.3'};
    id_default = {'select output file first'};

    config_data = get(src,'Data');
    selector = config_data(row,1);
    selector = selector{1};

    config_format = get(src,'ColumnFormat');
    switch selector
        case 'A'
            config_format{2} = id_group_1';
        case 'B'
            config_format{2} = id_group_2';
        case 'C'
            config_format{2} = id_group_3';
        otherwise
            config_format{2} = id_default;
    end
    config_data = { selector , 'select suboption...' };  %reset column 2
    set(src,'Data',config_data);
    set(src,'ColumnFormat',config_format);
end

function addRow(fh,k,lhp)
selector_1 = { 'A'; 'B' ; 'C' };
selector_2 = { 'first select first row!' };

defaultData =  {'select main option...', 'select suboption...'};
columnformat = { {selector_1{:}}, selector_2};
columneditable =  [true true];

th = uitable(fh,'Units','normalized','Position',[0 1-(k+1)*lhp 1 lhp],...
              'Data', defaultData,... 
              'ColumnName', [],...
              'ColumnWidth', {200 200},...
              'ColumnEditable', columneditable,...
              'ColumnFormat', columnformat,...  
              'RowName',[],...
              'Tag','value',...
              'UserData',k,...
              'SelectionHighlight','off',...
              'CellEditCallback',@edit);
end

function store(~,~)
ui = findobj(0,'Type','uitable','Tag','value');
L = numel(ui);
output = cell(L,2);
order = zeros(L,1);
for ii=1:L;
    output(ii,:) = get(ui(ii),'Data');
    order(ii)    = get(ui(ii),'UserData');
end
[~,idx] = sort(order);    %as order of handles unequals displayed order
assignin('base','output',output(idx,:));
end

次のように表示されます。

ファイナルテーブル

于 2013-10-24T15:18:46.893 に答える