滑块在使用后从 GUI 中消失

Slider disappears from GUI after being used

我尝试以编程方式制作 MATLAB GUI,但遇到了 滑块在使用后消失的问题。我隔离了问题以保持代码简短。在此 GUI 中,我想在每次使用滑块时刷新 plotmatrix(忽略滑块的值与我的程序完全无关的事实,如前所述,我真的想保持代码干净,这就是我的原因也删除了此功能)。这是代码(你必须 运行 它作为函数):

function WhosebugQuestion_GUI()
    % clear memory
    close all; clc;

    % initialize figure
    f = figure;

    % create main axes
    AX_main = axes('Parent',f,...
        'Units','normalized','Position',[.1 .2 .8 .7]);

    % create slider
    uicontrol('Parent',f,...
        'Style','slider','Callback',{@sliderCallback,AX_main},...
        'Units','normalized','Position',[0.05 0.05 0.9 0.05]);

    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix');
end

function sliderCallback(~,~,AX_main)   % callback for slider
    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix NEW');
end

感谢任何帮助!我想我误解了 AXES 的概念。当我绘制到我创建的 AXES 手柄时,为什么图形的其他部分也会受到影响?如果有人能向我解释一下这个图形句柄系统的基本工作原理,那就太好了!

当你调用plotmatrix时,函数会完全重绘图形, 要保存其他元素,您应该使用 hold on; hold off; 语句:

function WhosebugQuestion_GUI()
    % clear memory
    clear; close all; clc;

    % initialize figure
    f = figure;

    % create main axes
    AX_main = axes('Parent',f,...
        'Units','normalized','Position',[.1 .2 .8 .7]);

    % create slider
    uicontrol('Parent',f,...
        'Style','slider','Callback',{@sliderCallback,AX_main},...
        'Units','normalized','Position',[0.05 0.05 0.9 0.05]);

    plotmatrix(AX_main,randn(500,3));
    title('Random Plotmatrix');
end

function sliderCallback(~,~,AX_main)   % callback for slider
    hold on;
    plotmatrix(AX_main,randn(500,3));
    hold off;
    title('Random Plotmatrix NEW');
end

虽然 是正确的,但这种行为已经足够奇怪了,我很好奇它背后的原因。

逐步查看 plotmatrix 的源代码,我们可以找到删除滑块对象的行:

% Create/find BigAx and make it invisible
BigAx = newplot(cax);

这里没有什么明显的,newplot 是做什么的?

Use newplot at the beginning of high-level graphics code to determine which figure and axes to target for graphics output. Calling newplot can change the current figure and current axes. Basically, there are three options when you are drawing graphics in existing figures and axes:

  • Add the new graphics without changing any properties or deleting any objects.

  • Delete all existing objects whose handles are not hidden before drawing the new objects.

  • Delete all existing objects regardless of whether or not their handles are hidden, and reset most properties to their defaults before drawing the new objects (refer to the following table for specific information).

哦...

所以newplot正在删除滑块对象。


那么为什么 hold 阻止滑块被删除,尽管它是轴方法而不是图形方法?首先,请查看文档中的 "Algorithms" 主题:

The hold function sets the NextPlot property of the Axes or PolarAxes object to either 'add' or 'replace'.

因此 hold on 将当前轴的此项设置为 'add'。但是,由于我目前无法弄清楚的原因,这个 也将图形的 NextPlot 设置为 add

我们可以通过一个简短的代码片段看到这一点:

f = figure('NextPlot', 'replacechildren'); 
ax = axes; 
fprintf('NextPlot Status, base:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)
hold on
fprintf('NextPlot Status, hold on:\nFig: %s, Ax(1): %s\n\n', f.NextPlot, ax.NextPlot)

打印:

NextPlot Status, base:
Fig: replacechildren, Ax(1): replace

NextPlot Status, hold on:
Fig: add, Ax(1): add

奇怪的行为,但我不会详述。


为什么这很重要?返回 newplot 文档。首先,newplot 读取图的 NextPlot 属性 以确定要做什么。默认情况下,图形的 NextPlot 属性 设置为 'add',因此它将保留所有当前图形对象,但 plotmatrix 明确更改此:

if ~hold_state
    set(fig,'NextPlot','replacechildren')
end

所以 newplot 来自:

Draw to the current figure without clearing any graphics objects already present.

收件人:

Remove all child objects whose HandleVisibility property is set to on and reset figure NextPlot property to add.

This clears the current figure and is equivalent to issuing the clf command.

这解释了滑块消失的原因以及 hold on 解决问题的原因。


根据 newplot 的文档,我们还可以设置滑块 UIcontrol 的 HandleVisibility 以防止其被破坏:

% create slider
uicontrol('Parent',f,...
    'Style','slider','Callback',{@sliderCallback,AX_main},...
    'Units','normalized','Position',[0.05 0.05 0.9 0.05], ...
    'HandleVisibility', 'off');