删除或移动后刷新所有绘制点的位置 - Matlab App 设计器

ali*_*azi 6 matlab matlab-app-designer

我做了一个带有两个按钮和轴的应用程序设计器 GUI。第一个(LoadimageButton)正在加载纸张图像,我可以标记点,直到按转义键。第二个按钮是打印点坐标(PositionButton)。

我注意到按下两个按钮后我可以移动轴上的点并更改它们的位置或删除它们。问题是,当我按下删除键(在上下文菜单中)时,按下 PositionButton 后出现此错误:

Error using images.roi.Point/get
Invalid or deleted object.

Error in tempDrwPnt1/PositionButtonPushed (line 61)
positions = cell2mat(get(app.pointhandles, 'position'))

Error while evaluating Button PrivateButtonPushedFcn.
Run Code Online (Sandbox Code Playgroud)

删除点后如何刷新 app.pointhandles?

代码:

function LoadimageButtonPushed(app, event)
            imshow('peppers.png','Parent',app.ImageAxes); 
          
            userStopped = false; 
            app.pointhandles = gobjects(); 
                   while ~userStopped
                        roi = drawpoint(app.ImageAxes); 
                        if ~isvalid(roi) || isempty(roi.Position)
                            % End the loop
                            userStopped = true;
                        else
                            % store point object handle
                            app.pointhandles(end+1) = roi;
                        end
                   end 
            

            addlistener(roi,'MovingROI',@allevents);
            addlistener(roi,'ROIMoved',@allevents);
  
            app.pointhandles(1) = []; 
            
            function allevents(src,evt)
                evname = evt.EventName;
                switch(evname)
                    case{'MovingROI'}
                        disp(['ROI moving previous position: ' mat2str(evt.PreviousPosition)]);
                        disp(['ROI moving current position: ' mat2str(evt.CurrentPosition)]);
                    case{'ROIMoved'}
                        disp(['ROI moved previous position: ' mat2str(evt.PreviousPosition)]);
                        disp(['ROI moved current position: ' mat2str(evt.CurrentPosition)]);
                end
            end 
end


% Button pushed function: PositionButton
function PositionButtonPushed(app, event) 
positions = cell2mat(get(app.pointhandles, 'position'))
end
Run Code Online (Sandbox Code Playgroud)

Wol*_*fie 4

您可以在函数中添加检查PositionButtonPushed每个元素是否有效pointhandles,如果有效则报告它,如果无效则删除它

就像是

function PositionButtonPushed(app, event)
    nPts = numel(app.pointhandles);
    positions = NaN(nPts,2); % array to hold positions
    for iPt = nPts:-1:1 % loop backwards so we can remove elements without issue
        if isvalid( app.pointhandles(iPt) )
            positions(iPt,:) = get(app.pointhandles(iPt),'position');
        else
            % No longer valid (been deleted), remove the reference
            app.pointhandles(iPt) = [];
            % Also remove from the positions output
            positions(iPt,:) = [];
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

我现在还没有可用的兼容 MATLAB 版本来测试这一点,但我假设内置函数isvalid适用于Point对象,否则您将必须添加自己的有效性检查。或者,您可以try获取该位置,并在 中进行删除(由else上面处理)catch,但我通常建议反对try/catch如果您可以检查特定(已知)问题。

我经常使用类似的东西(例如对于轴),但将无效句柄的清理功能捆绑到其自己的函数中。在这种情况下,它可以让您在获取剩余有效点的位置之前添加单个函数调用。

我还通过使用使其更加简洁arrayfun,但在幕后它的方法与上面的循环相同:

function PositionButtonPushed(app, event )
    app.checkHandleValidity(); % cleanup handles just in case

    positions = cell2mat(get(app.pointhandles, 'position'));
end

function checkHandleValidity( app )
   bValid = arrayfun( @isvalid, app.pointhandles ); % Check validity
   app.pointhandles( ~bValid ) = [];                % Remove invalid elements
end
Run Code Online (Sandbox Code Playgroud)