the*_*alk 7 matlab user-interface user-controls callback matlab-uitable
对于我正在编程的用户界面uitable.用户在第一列中选择选项A,B或C,第二列中的子选项取决于在第一列中选择的内容,A.1,A.2或A.3或B.1,B.2或B.3或C相同

该表的代码可以在附录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对象属性的复杂解决方法等.提前谢谢!
我在此处的评论中包含了讨论以保持概述:
如果您想尝试一下,可以复制代码并按照以下步骤重现不良行为:
似乎不是寻找最后一个选项,而应该查看相关选项.因此,要么确保单击子选项执行"查找"以查看其中包含哪个主选项,
这正是我正在寻找的!但我怎么能这样做?如何检测点击,获取列和行索引,设置正确
ColumnFormat,然后最终让单元格弹出.我到目前为止看到的唯一可能性是CellSelectionCallback,但是在单元格已经弹出无效选项之后执行.我需要一种ClickedCallback,就像有的一样pushbuttons
或确保选择主选项仅设置该行的子选项.
这是不可能的,您无法为需要修改的某一行设置子选项ColumnFormat,这会影响整个表而不仅仅是一行.
尽管我高度赞赏 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)
提出:
