是否可以防止弹出一个合适的弹出菜单?或者:如何通过单击一个单元格返回行和列索引来获取回调?

the*_*alk 7 matlab user-interface user-controls callback matlab-uitable

对于我正在编程的用户界面uitable.用户在第一列中选择选项A,B或C,第二列中的子选项取决于在第一列中选​​择的内容,A.1,A.2或A.3B.1,B.2或B.3C相同

在此输入图像描述

该表的代码可以在附录A中找到.

当用户首先定义主选项时,子菜单会自动减少到仅有效选项.这是由evalulating实现的CellEditCallback第1列和重置ColumnFormat列2(函数modifySelection附录B)如果用户现在意识到,他犯了一个错误,需要编辑子选项另一次,则ColumnFormat仍然按照以前的编辑组主要选项和有效选项不可用,除非他再次重新选择主选项.(见图中的蓝色突出显示).

为了解决这个问题,我还实现了CellSelectionCallback调用函数justifySelection(在附录B中),该函数通过选择进行检查,在第1列中选择了哪个选项以再次为第2列提供正确的子选项.但是由于此回调对选择作出反应,我需要选择两次,一次触发CellSelectionCallback,另一次实际选择.对于大型桌子,这可能非常烦人!

所以我的问题是:

有没有办法阻止第2列中的弹出菜单弹出,直到它找出相应列1的内容是什么,所以它会立即提供有效的选择?

要么:

如何检测单元格上的鼠标单击并获取行和列索引?但是没有调用以下选择并弹出动作?

我已经耙了所有可用的属性,但没有发现任何有用的东西.也许人们可以使用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
Run Code Online (Sandbox Code Playgroud)

最后是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
Run Code Online (Sandbox Code Playgroud)

赏金:为什么只是+50? - 一旦有了正确的初步想法,我想这要么不可能,要么答案很简单.我不是在寻找使用java对象属性的复杂解决方法等.提前谢谢!


我在此处的评论中包含了讨论以保持概述:

如果您想尝试一下,可以复制代码并按照以下步骤重现不良行为:

  1. 在第一行中选择主选项A.
  2. 然后第一行中的子选项包含选项A.1,A.2和A.3.
  3. 在第二行中选择主选项B,因此第二行中子选项的选项是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,这会影响整个表而不仅仅是一行.

the*_*alk 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

提出:

决赛桌