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

本文介绍了是否可以防止弹出一个合适的弹出菜单?或者:如何通过单击单元格,返回行来获取回调 &列索引?的处理方法,对大家解决问题具有一定的参考价值

问题描述

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

相同

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

当用户首先定义主选项时,子选项会自动相应地减少为只有有效的选项.这是通过评估第 1 列的 CellEditCallback 并重置第 2 列的 ColumnFormat 来实现的.(附录 B 中的函数 modifySelection强>)如果用户现在意识到自己犯了一个错误,需要再次编辑子选项,那么 ColumnFormat 仍然根据之前编辑的主选项设置,除非他重新选择,否则有效选项不可用另一个时间的主要选择.(参见图片中的蓝色突出显示).

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

所以我的问题是:

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

或者:

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

我已经在搜索所有 可用属性但没有找到任何有用的东西.或许可以使用 ButtonDownFcn 做某事,但是如何获取单元格索引呢?BusyAction 属性怎么样,它如何用于我的目的?

有什么想法吗?

我很抱歉提前用这么多代码轰炸你,它已经是最小的例子,但完全可执行,所以你可以尝试一下.

<小时>

附录 A/B

函数 fancyUitable选择器_1 = {'A';'B' ;'C' };selector_2 = { '先选择第一行!'};h = figure('位置',[200 100 268 120],'numbertitle','off','MenuBar','none');defaultData = repmat( {'选择主选项...', '选择子选项...'} ,5,1);列名 = {'选项',...'子选项'};columnformat = { {{selector_1{:}}, selector_2 };columneditable = [true true];t = uitable(h,'单位','归一化','位置',[0 0 1 1],...'数据',默认数据,...'列名',列名,...'列可编辑',列可编辑,...'列格式',列格式,...'行名',[],...'CellEditCallback',@modifySelection,...'CellSelectionCallback',@justifySelection);设置(h,'标签''Config_figure')设置(t,'标签''Config_table')结尾% **附录 B**%(同一个函数文件的一部分)函数 modifySelection(~,evt_edit)如果 evt_edit.Indices(2) == 1modifyPopup(evt_edit.Indices(1));结尾结尾函数 justifySelection(~,evt_select)尝试 % 抑制不重要的错误如果 evt_select.Indices(2) == 2modifyPopup(evt_select.Indices(1));结尾结尾结尾

<小时>

最后是单个函数modifyPopup,它重写了Columnformat:

函数 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 = {'先选择主选项'};myfigure = findobj('Tag','Config_figure');config_data = get(findobj(myfigure,'Tag','Config_table'),'Data');选择器 = config_data(row,1);选择器 = 选择器{1};config_format = get(findobj(myfigure,'Tag','Config_table'),'ColumnFormat');开关选择器案例A"config_format{2} = id_group_1';案例B"config_format{2} = id_group_2';案例C"config_format{2} = id_group_3';否则config_format{2} = id_default;结尾set(findobj(myfigure,'Tag','Config_table'),'ColumnFormat',config_format)结尾

赏金:为什么只是 +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,这会影响整个表格而不仅仅是一行.

解决方案

虽然我非常感谢 Rody Oldenhuis 的努力和解决方案,他当然应该得到这个奖项,但他的解决方案需要对我的代码进行大量更改,所以我一直试图找到一个更简单的解决方案.在这里,终于 99% 没有错误.

(函数脚本中的所有代码部分)

函数 fancyUitable关闭所有%基本属性line_height = 21.32;table_height = 6*line_height;lh = line_height/table_height;CW = 200;%列宽h = figure('位置',[200 100 2*cw+2 table_height],...'numbertitle','off','MenuBar','none');%标头uitable(h,'单位','归一化','位置',[0 1-lh 1 lh],...'ColumnWidth', {cw cw},...'列名',{'选项''子选项'},...'行名',[]);%button(目前没有图标)来存储表格tbar = uitoolbar(h);uipushtool(tbar,'ClickedCallback',@store);% addrow(figurehandle,行数,百分比线高)% 每个函数调用创建一个新行,稍后动态addRow(h,1,lh);addRow(h,2,lh);addRow(h,3,lh);addRow(h,4,lh);addRow(h,5,lh);结尾

<小时>

函数编辑(src,evt)如果 evt.Indices(2) == 1modifyPopup(src,evt.Indices(1));结尾% 禁用单元格选择突出显示,当一个人跳到下一个表时,% 虽然有点滞后fh = get(src,'父');复制obj(src,fh);删除(src);结尾函数 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 = {'先选择输出文件'};config_data = get(src,'数据');选择器 = config_data(row,1);选择器 = 选择器{1};config_format = get(src,'ColumnFormat');开关选择器案例A"config_format{2} = id_group_1';案例B"config_format{2} = id_group_2';案例C"config_format{2} = id_group_3';否则config_format{2} = id_default;结尾config_data = { selector , '选择子选项...' };%重置第 2 列设置(源代码,'数据',配置数据);set(src,'ColumnFormat',config_format);结尾

<小时>

函数 addRow(fh,k,lhp)选择器_1 = {'A';'B' ;'C' };selector_2 = { '先选择第一行!'};defaultData = {'选择主选项...', '选择子选项...'};columnformat = { {{selector_1{:}}, selector_2};columneditable = [true true];th = uitable(fh,'单位','归一化','位置',[0 1-(k+1)*lhp 1 lhp],...'数据',默认数据,...'列名',[],...'列宽',{200 200},...'列可编辑',列可编辑,...'列格式',列格式,...'行名',[],...标签"、价值"、...'用户数据',k,...'SelectionHighlight''关闭',...'CellEditCallback',@edit);结尾

<小时>

函数存储(~,~)ui = findobj(0,'Type','uitable','Tag','value');L = 数字(ui);输出=细胞(L,2);订单=零(L,1);对于 ii=1:L;输出(ii,:) = get(ui(ii),'数据');order(ii) = get(ui(ii),'UserData');结尾[~,idx] = 排序(顺序);%as 句柄顺序不等于显示顺序assignin('base','output',output(idx,:));结尾

提出:

For an user interface I'm programming an uitable. The user chooses an option A,B or C in the first column and the suboption in the second column depends on what was chosen in the first, either A.1,A.2 or A.3 or B.1,B.2 or B.3 or the same for C

The code for the table can be found in Appendix A.

When the user first defines the main option, then automatically the suboptions are reduced accordingly to only valid choices. This is realized by evalulating the CellEditCallback for column 1 and resetting the ColumnFormat for column 2. (function modifySelection in Appendix B) If the user now realizes he made a mistake and needs to edit a suboption another time, then the ColumnFormat is still set according to the previous edited main option and the valid choices are not available unless he re-chooes the main option another time. (see the blue highlighting in picture).

To resolve this, I also implemented the CellSelectionCallback calling the function justifySelection (in Appendix B), which is checking by selection, which option was chosen in column 1 to offer again the right suboptions for column 2. But as this callback reacts on selection, I need to select twice, one time to trigger the CellSelectionCallback and another to actually get my choices. For large tables, this can be very annoying!

So my question is:

Is there a way to prevent the popup menu in column 2 from popping up, until it found out what's the content of the according column 1, so it immediately offers the valid choices?

Or:

How could I detect a mouse click on a cell and get the row and column-index? But without invoking the following selection and popping up action?

I was already raking all available properties but didn't found anything which could be useful. Maybe one could do something using the ButtonDownFcn, but how to get the cell indices? What about the BusyAction property, how can that be used for my purpose?

Any ideas?

I'm sorry in advance to bomb you with so much code, it's already the most minimal example, but fully executable, so you can try it out.


Appendix 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


and finally the single function modifyPopup which rewrites the 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

Bounty: Why just +50? - I guess it's either not possible or the answer is easy, once one had the right initial idea. I'm not looking a for a complex workaround using java object properties etc. Thank you in advance!


I include the discussion from the comments here to keep the overview:

If you want to try it out, you can copy the code and follow these steps to reproduce the undesired behaviour:

  1. select main option A in the first row.
  2. the suboption in the first row then contains the choices A.1, A.2 and A.3.
  3. select main option B in the second row, therefore the choices for the suboption in the second row are B.1, B.2 and B.3
  4. BUT NOW you want to change the suboption in the first row (directly); you would expect to get the choices A.1, A.2 and A.3; but you don't. You get offered B.1, B.2 & B.3; - Because the last main option you selected was B (though in a diffrent row).

It seems that instead of looking for the last option, you should look at the relevant option. So either make sure that clicking on a suboption does a 'lookup' to see which main option there is,

Thats exactly what I'm looking for! But how could I do that? How to detect the click, get the column&row indices, set the right ColumnFormat and then finally let the cell pop up. The only possibility I see until now is the CellSelectionCallback, but it is executed after the cell already popped up with the invalid choices. I'd need a kind of ClickedCallback, like there is for pushbuttons

or make sure that selecting a main option only sets the suboptions for that row.

That's not possible, you can't set a suboption for a certain row as you need to modify ColumnFormat, which affects the whole table and not just one row.

解决方案

Though I highly appreciate the effort and the solution of Rody Oldenhuis and he definetely deserved the award, his solution would have required a lot of changes in my code, so I kept trying to find a simpler solution. Here it is, finally 99% bug-free.

(all code parts within on function script)

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

brings up:

这篇关于是否可以防止弹出一个合适的弹出菜单?或者:如何通过单击单元格,返回行来获取回调 &amp;列索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2

admin_action_{$_REQUEST[‘action’]}

do_action( "admin_action_{$_REQUEST[‘action’]}" )动作钩子::在发送“Action”请求变量时激发。Action Hook: Fires when an ‘action’ request variable is sent.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$_REQUEST['action']引用从GET或POST请求派生的操作。源码(Source)更新版本源码位置使用被使用2.6.0 wp-admin/admin.php:...

日期:2020-09-02 17:44:16 浏览:1127

admin_footer-{$GLOBALS[‘hook_suffix’]}

do_action( "admin_footer-{$GLOBALS[‘hook_suffix’]}", string $hook_suffix )操作挂钩:在默认页脚脚本之后打印脚本或数据。Action Hook: Print scripts or data after the default footer scripts.目录锚点:#说明#参数#源码说明(Description)钩子名的动态部分,$GLOBALS['hook_suffix']引用当前页的全局钩子后缀。参数(Parameters)参数类...

日期:2020-09-02 17:44:20 浏览:1032

customize_save_{$this->id_data[‘base’]}

do_action( "customize_save_{$this-&gt;id_data[‘base’]}", WP_Customize_Setting $this )动作钩子::在调用WP_Customize_Setting::save()方法时激发。Action Hook: Fires when the WP_Customize_Setting::save() method is called.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_data...

日期:2020-08-15 15:47:24 浏览:775

customize_value_{$this->id_data[‘base’]}

apply_filters( "customize_value_{$this-&gt;id_data[‘base’]}", mixed $default )过滤器::过滤未作为主题模式或选项处理的自定义设置值。Filter Hook: Filter a Customize setting value not handled as a theme_mod or option.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分,$this->id_date['base'],指的是设置...

日期:2020-08-15 15:47:24 浏览:866

get_comment_author_url

过滤钩子:过滤评论作者的URL。Filter Hook: Filters the comment author’s URL.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/comment-template.php:32610...

日期:2020-08-10 23:06:14 浏览:903

network_admin_edit_{$_GET[‘action’]}

do_action( "network_admin_edit_{$_GET[‘action’]}" )操作挂钩:启动请求的处理程序操作。Action Hook: Fires the requested handler action.目录锚点:#说明#源码说明(Description)钩子名称的动态部分$u GET['action']引用请求的操作的名称。源码(Source)更新版本源码位置使用被使用3.1.0 wp-admin/network/edit.php:3600...

日期:2020-08-02 09:56:09 浏览:848

network_sites_updated_message_{$_GET[‘updated’]}

apply_filters( "network_sites_updated_message_{$_GET[‘updated’]}", string $msg )筛选器挂钩:在网络管理中筛选特定的非默认站点更新消息。Filter Hook: Filters a specific, non-default site-updated message in the Network admin.目录锚点:#说明#参数#源码说明(Description)钩子名称的动态部分$_GET['updated']引用了非默认的...

日期:2020-08-02 09:56:03 浏览:834

pre_wp_is_site_initialized

过滤器::过滤在访问数据库之前是否初始化站点的检查。Filter Hook: Filters the check for whether a site is initialized before the database is accessed.目录锚点:#源码源码(Source)更新版本源码位置使用被使用 wp-includes/ms-site.php:93910...

日期:2020-07-29 10:15:38 浏览:809

WordPress 的SEO 教学:如何在网站中加入关键字(Meta Keywords)与Meta 描述(Meta Description)?

你想在WordPress 中添加关键字和meta 描述吗?关键字和meta 描述使你能够提高网站的SEO。在本文中,我们将向你展示如何在WordPress 中正确添加关键字和meta 描述。为什么要在WordPress 中添加关键字和Meta 描述?关键字和说明让搜寻引擎更了解您的帖子和页面的内容。关键词是人们寻找您发布的内容时,可能会搜索的重要词语或片语。而Meta Description则是对你的页面和文章的简要描述。如果你想要了解更多关于中继标签的资讯,可以参考Google的说明。Meta 关键字和描...

日期:2020-10-03 21:18:25 浏览:1619

谷歌的SEO是什么

SEO (Search Engine Optimization)中文是搜寻引擎最佳化,意思近于「关键字自然排序」、「网站排名优化」。简言之,SEO是以搜索引擎(如Google、Bing)为曝光媒体的行销手法。例如搜寻「wordpress教学」,会看到本站的「WordPress教学:12个课程…」排行Google第一:关键字:wordpress教学、wordpress课程…若搜寻「网站架设」,则会看到另一个网页排名第1:关键字:网站架设、架站…以上两个网页,每月从搜寻引擎导入自然流量,达2万4千:每月「有机搜...

日期:2020-10-30 17:23:57 浏览:1262