【问题标题】:Programmatically save changes of an editable uitable以编程方式保存可编辑 uitable 的更改
【发布时间】:2013-10-23 06:26:13
【问题描述】:

我在 Matlab 中创建了一个 UItable,其中填充了各种值和选项。 它看起来像:

对应的代码如下:

selector_1 = { 'A'; 'B' ; 'C' };
selector_2 = { 'A.1'; 'A.2'; 'A.3'; ...
               'B.1'; 'B.2'; 'B.3'; ...
               'C.1'; 'C.2'; 'C.3' };

rows = 5;           

f = figure('name','Configuration of output','Position',[200 200 430 25+rows*20],'numbertitle','off','MenuBar','none');

dat =  {'select outputfile...', 'select identifier...', 'Specifier',  'Index'};
dat = repmat(dat,rows,1);
columnname =   {'Output file                   ',...
                'Identifier                    ',...
                'Specifier          ', 'Index'};
columnformat = { {selector_1{:}}, {selector_2{:}}, 'char', 'numeric' };
columneditable =  [true true true true]; 
t = uitable('Units','normalized','Position',...
            [0 0 1 1], 'Data', dat,... 
            'ColumnName', columnname,...
            'ColumnFormat', columnformat,...
            'ColumnEditable', columneditable,...
            'RowName',[]);
set(t, 'Data', dat,'celleditcallback','get(t,''Data'')');

所以我运行代码,图就打开了。因此,底层脚本已经完成。 当我现在编辑表格时,我的 uitable 对象已更改,完成后我可以通过以下方式获得最终配置:

finalconfig =  get(t,'Data');

但问题是我需要手动输入这一行,因为我的脚本已经完成。如果我将此行放在脚本的末尾,则会出现错误。

所以我考虑使用以下循环来检测我何时关闭表并存储最后一个配置

while ~isempty(findobj('name','Configuration of output'))
    % some action
end
finalconfig =  get(t,'Data');

我尝试了将所有内容放入循环中,整个脚本,包括celleditcallback 在内的set 命令和其他东西,但没有任何效果。当我编辑一个值时,要么我的脚本卡在循环中,要么我的表格的显示没有更新。我还在不同的位置尝试了drawnow。如何处理这种情况?如何自动存储我的最终结果? 我认为“关闭窗口”是最好的检测动作,因为我认为我无法实现“保存”按钮。我还尝试使用GUIDE 创建一个 gui,但完全迷路了,我希望没有解决它。


编辑: 我现在能够实现“保存”按钮并尝试如下回调:

uimenu('Label','Save configuration','Callback',@saveConfig);
function saveConfig(~,~)
        output = get(t,'Data',);
        save([pwd 'output.mat'],'output');
end

我还按照 Lucius Domitius Ahenobarbus 的建议实现了自定义 CloseRequestFcn。但后来我遇到了以下任一问题:

1) 我将所有内容定义为脚本,一切正常,但我需要将 @saveConfig(实际上是我最喜欢的)或 @my_Closefcn 等函数定义为我工作区中的唯一函数文件,我很难传递正确的参数因为dat 总是保持不变,即使它实际上已经改变了。 (example from the mathworks site 有效!但它不需要额外的参数。)

2)当我使用时

function configuration
% my script from above
end

我可以直接(嵌套)实现@saveConfig@my_Closefcn,我猜参数的传递可以正常工作。但是我的表格的编辑不再起作用,抛出以下错误:

使用 handle.handle/get 时出错

无效或已删除的对象。

评估合适的 CellEditCallback 时出错

如何解决? 现在我知道我什至可以将按钮添加到我真的很想避免使用 GUIDE 的 uitable 中。 我上面的代码是可执行的,所以如果你尝试看看我的实际问题是什么,我会很高兴,因为它很难描述。

【问题讨论】:

    标签: matlab user-interface callback matlab-uitable


    【解决方案1】:

    取决于是否使用 GUIDE:

    使用 CloseRequestFcn->

    不使用 GUIDE:

    %write your own CloseRequestFcn and set the figure CloseRequest-Callback to it:
    set(gcf,'CloseRequestFcn',@my_closefcn)
    %use gcf or the handle of the figure directly
    

    并定义 my_closefcn 包括图形句柄的删除语句,否则图形将不会关闭:)

    有关“重新定义 CloseRequestFcn”的更多信息,请参阅文档。

    使用指南:

    您可以通过检查图来编辑 CloseRequestFcn。有一个名为 CloseRequestFcn 的字段将自动创建函数,您无需关心获取句柄。它看起来像这样:

    function figure1_CloseRequestFcn(hObject, eventdata, handles)
    % hObject    handle to figure1 (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    
    % Hint: delete(hObject) closes the figure
    delete(hObject);
    

    现在在删除图之前,您应该能够获取 uitable 的数据(如果您有句柄),我建议将数据分配给基本工作区,例如:

    assignin('base', 'finalTableData', get(myTableHandle,'Data'));
    

    编辑

    因为我不够清楚,请看这个例子:

    (在一个脚本中使用)->

    function test
    h=figure;
    x=1:10;
    mytable=uitable(h,'Data',x);
    set(h,'CloseRequestFcn',@myCloseFcn)
    %give a unique Tag:
    set(h,'Tag', 'myTag')
    set(mytable,'Tag','myTableTag')
    end
    
    function myCloseFcn(~,~)
    myfigure=findobj('Tag','myTag');
    myData=get(findobj(myfigure,'Tag','myTableTag'),'Data')
    assignin('base','myTestData',myData)
    delete(myfigure)
    end
    

    其实你的Closereq-Callback的参数不用管,只要你知道怎么找图的句柄就行了!只需为您的身材/合适的人提供一些您以后能够识别的东西。我使用了“标签”,因为我首先想到的是,但也会有其他参数。

    【讨论】:

    • 我不能让它工作,请看看我编辑的问题。我认为这是一个好方法,虽然我更喜欢“保存”按钮。这两种方法仍然存在同样的困难。
    • 现在它甚至适用于我的示例。您的示例和我的示例之间的唯一区别是我使用了set(t, 'Data', dat,'celleditcallback','get(t,''Data'')');,因为这对我来说似乎是绝对必要的。但这显然是无用的,而且jsut会制造麻烦。非常感谢!我希望现在能够在保存按钮中实现你的功能,但应该是一样的。
    • 和另一个简短的小问题:在您的示例中,我如何获得第一个函数的变量x,但在第二个函数中?它既不是我身材的一部分,也不是我桌子的一部分。而且我不知道如何访问函数工作区。
    • 为此,我建议使用图形的guidata-property。只需将其放入 struct UserData 中,如果您正确保存它,它将在稍后出现。例如在closereq-fcn中它看起来像:get(myfigure,'UserData');
    【解决方案2】:

    我只能想到直接在代码之后运行代码或在代码内部运行代码之间的两个区别。

    1.范围

    也许您实际上是在使用函数,而不是脚本。在这种情况下,问题可能是在您的函数内部,您需要的东西超出了范围。

    2。时机

    虽然这种情况很少见,但有时计算机似乎已经完成,而实际上它仍然很忙(几毫秒左右)。


    以下是一般方法的步骤:

    1. 确保在您要插入命令的位置有一个简单的行(例如1==1
    2. 在该行放置一个断点
    3. 一旦 matlab 在断点处停止,请稍等片刻,然后尝试运行您的命令。

    如果它有效,我会打赌第 2 个问题。尝试在您的命令前放置 pause(1),看看是否有帮助。

    如果它不起作用,您很可能会遇到第 1 个问题。现在需要找到合适的位置来放置您的命令。如果命令不能放在代码中的其他地方,也许可以试试丑陋的evalin(,'base')。但是,后者确实应该被视为一种解决方法而不是解决方案。

    【讨论】:

      猜你喜欢
      • 2011-08-18
      • 2020-04-04
      • 2015-10-27
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多