MATLAB uicontrol 回调 return 矩阵

MATLAB uicontrol callback return matrix

原文post:

我的问题现在有了第二部分。 和以前一样,我正在绘制一个 19*1000*134 矩阵,这要归功于 Aero Engy 在上一个 post.

上的出色回答

我想在我的工作区中创建一个名为 clean 的向量,其长度为 134。

默认情况下,clean(i)(i 在 1 到 134 之间)的值将为 1——但是,如果我在 UI 界面上按下按钮,该值必须变为 0 .

我的代码如下,只是不要给我任何输出。该按钮似乎可以使用,但是当我关闭图形时,我没有清理矢量。

function cleanData(data);
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a =   axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s =   uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
                   'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l =   uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
                   'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
                   'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,clean,s});

stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];               
changeChannel(l,[],a,s,data)

function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500;  %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position

function sliderChange(s,evtData,a)
viewI = round(s.Value);
disp(['Current Epoch: ' num2str(viewI)]) %console print
xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])

function notClean(c,evtData,clean,s)
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print

我做错了什么?

奖金:如果

就好了

感谢您的帮助,我是 MATLAB 的新手,即使我提高很快,我也远未完全理解这段代码。

在 notClean 回调中,我将 clean 作为全局调用。我也将它作为输入删除了...因为它是全局的,所以没有必要将它传入。

我还添加了每次按下按钮时滑块前进 1 的代码。

关闭 GUI 后在您的工作区中查看您标记的内容,您只需在命令行执行以下操作即可访问您的 clean 数组。 (数字是我标记为不干净的随机内容。

我现在必须离开,所以我无法解决关于更改频道和跳过 ~clean elementr 的第二个要点……但这应该不是很难。我会在几个小时后回到这里。

>> global clean
>> find(~clean)
ans =
  3  4  11 19

修改后的代码: 编辑:在跳过频道的边缘添加了代码保护。

function cleanData(data)
% data = rand(19,1000,134);
global clean
clean = ones(1,size(data,3));
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a =   axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s =   uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
                   'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l =   uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
                   'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
                   'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});

stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];               
changeChannel(l,[],a,s,data)

function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500;  %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position

function sliderChange(s,evtData,a)
global clean
persistent prevI

if isempty(prevI)
    prevI = 1;
end

viewI = round(s.Value);
sDir = sign(viewI - prevI);  %-1 if going backwards +1 if going forward
prevI = viewI;

if clean(viewI) == 0
    newPos = viewI + sDir;
    if newPos < 1 || newPos > s.Max
        return
    end
    s.Value = newPos; 
    sliderChange(s,[],a)
else
    disp(['Current Epoch: ' num2str(viewI)]) %console print
    xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])  
end


function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
if num+1 < s.Max
    s.Value = num+1;
    sliderChange(s,[],a)
end

将第二部分的代码修改为:

function cleanData(data);
% data = rand(19,1000,134);
f = figure('Units','Normalized','Position',[0.25 0.25 0.5 0.5]);
a =   axes('Units','Normalized','Position',[0.05 0.15, 0.75 0.75]);
s =   uicontrol(f, 'Style','Slider', 'Units','Normalized','Position',[0.05 0.025, 0.75 0.05],...
                   'Min',1,'Max',size(data,3),'Value',1, 'Callback',{@sliderChange,a});
l =   uicontrol(f, 'Style','listbox','Units','Normalized','Position',[0.85 0.15, 0.1, 0.75],...
                   'String',cellstr(num2str([1:size(data,1)]')),'Callback',{@changeChannel,a,s,data});
c = uicontrol(f, 'Style','pushbutton','Units','Normalized','String','Not clean',...
                   'Position',[0.85 0.025 0.1 0.05],'Callback',{@notClean,s,a});

stepSize = 1/(s.Max - s.Min);
s.SliderStep = [stepSize 2*stepSize];               
changeChannel(l,[],a,s,data)

function changeChannel(l,evtData,a,s,data)
cla(a);
chanNum = str2double(l.String{l.Value});
sR = 500;  %500Hz
tempData = reshape(data(chanNum,:,:),[],size(data,3)); %Reshape each epoch into a column
tempTime = [0:1/sR:(size(data,2)-1)/sR]' + (0:1:size(data,3)-1)*2; %Build time array
plot(a,tempTime,tempData) %plot all the lines
s.Value = 1; %Rest Slider Position

function sliderChange(s,evtData,a)
global clean
viewI = round(s.Value);
if clean(viewI) == 0
    s.Value = s.Value+1;
    sliderChange(s,[],a)
else
    disp(['Current Epoch: ' num2str(viewI)]) %console print
    xlim(a,[(viewI-1)*2 viewI*2] + [-.1 .1])  
end


function notClean(c,evtData,s,a)
global clean %Call the global
num = round(s.Value);
clean(num) = 0;
disp(['Epoch ' num2str(num) ' not clean']) %console print
%Advance to the next slider position.
s.Value = num+1;
sliderChange(s,[],a)