【问题标题】:Fatal error given by Matlab GUIMatlab GUI 给出的致命错误
【发布时间】:2011-08-03 07:58:30
【问题描述】:

已编辑帖子

这些是我使用您的模板创建的新功能来帮助我。 发生的事情是虽然代码工作正常,但“检查光标”框不在轴的顶部。事实上,它们相距甚远。我使用了一次 disp(axPos) 和 set(hAx, 'Units','pixels') ,一次用它注释掉了。它显示:

1.

 169.0000   71.0000  126.0000   51.0000
 94.0000  122.0000  126.0000   51.0000
 19.0000   71.0000  126.0000   51.0000
 94.0000   20.0000  126.0000   51.0000

哪个是轴的 GUIDE 坐标,而不是“当前点”显示的坐标

2.

33.6000    5.3846   25.2000    3.9231
18.6000    9.3077   25.2000    3.9231
3.6000    5.3846   25.2000    3.9231
18.6000    1.4615   25.2000    3.9231

我不知道这些来自哪里,但更接近它们需要的位置,但在左侧约 60 像素。

代码如下:

function HVACSM_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to HVACSM (see VARARGIN)

% Choose default command line output for HVACSM
handles.output = hObject;
NUM = 4;

imgOff1 = imread('cond.png');
imgOn1 = imread('condH.png');

imgOff2 = imread('comp.png');
imgOn2 = imread('compH.png');

imgOff3 = imread('evap.png');
imgOn3 = imread('evapH.png');

imgOff4 = imread('exp.png');
imgOn4 = imread('expH.png');

imgOff = cell(1,NUM);
imgOff{1} = imgOff1;
imgOff{2} = imgOff2;
imgOff{3} = imgOff3;
imgOff{4} = imgOff4;

imgOn = cell(1,NUM);
imgOn{1} = imgOn1;
imgOn{2} = imgOn2;
imgOn{3} = imgOn3;
imgOn{4} = imgOn4;

%# setup axes
hAx = zeros(1,NUM);
hImg = zeros(1,NUM);
hAx = [handles.axes1 handles.axes2 handles.axes3 handles.axes4];
hImg(1) = imagesc(imgOff{1}, 'Parent',hAx(1));
hImg(2) = imagesc(imgOff{2}, 'Parent',hAx(2));
hImg(3) = imagesc(imgOff{3}, 'Parent',hAx(3));
hImg(4) = imagesc(imgOff{4}, 'Parent',hAx(4));
set(hAx, 'XTick',[], 'YTick',[],'Box', 'on')

%# get corner-points of each axis
set(hAx, 'Units','pixels')
axPos = cell2mat( get(hAx,'Position') );
disp(axPos)
p = zeros(5,2,NUM);
for k=1:NUM
    p(:,:,k) = bsxfun(@plus, axPos(k,1:2), ...
        [0 0; axPos(k,3) 0; axPos(k,3:4); 0 axPos(k,4); 0 0]);
end
handles.p = p;
handles.hAx = hAx;
handles.hImg = hImg;
handles.imgOff = imgOff;
handles.imgOn = imgOn;
% Update handles structure
guidata(hObject, handles);



function figure1_WindowButtonMotionFcn(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)

pos = get(hObject,'CurrentPoint');%CurrentPoint
posx = pos(1); posy = pos(2);

%Display to check to see if the position is working
posx = num2str(posx);
posy = num2str(posy);

set(handles.Xpos,'String',posx);
set(handles.Ypos,'String',posy);

p = handles.p;
hImg = handles.hImg;
hAx = handles.hAx;
imgOff = handles.imgOff;
imgOn = handles.imgOn;


%# for each axis, determine if we are inside it
    for i=1:numel(hImg)
        if inpolygon(pos(1),pos(2), p(:,1,i),p(:,2,i))
            set(hImg(i), 'CData',imgOn{i})
            set(hAx(i), 'LineWidth',3, 'XColor','r', 'YColor','r')
        else
            set(hImg(i), 'CData',imgOff{i})
            set(hAx(i), 'LineWidth',1, 'XColor','k', 'YColor','k')
        end
    end

这些是带有原始代码“set(hAx,'Units','pixels')”的hitboxes

注意* 其他的都在屏幕右上角之外,或者应该是。

这些是带有更改代码“set(hAx, 'Units','characters')”的命中框

注意* 这与注释掉代码时发生的情况完全相同。

8 月 2 日测试 .

.

.

.

附录 原帖

运行我的 GUI [Fatal Error] 后出现此错误:-1:-1: Premature end of file。

它发生在这段代码中:

function figure1_WindowButtonMotionFcn(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)

pos = get(hObject,'CurrentPoint');

%CurrentPoint

posx = pos(1); posy = pos(2);

%Display to check to see if the position is working

posx = num2str(posx); posy = num2str(posy);

 set(handles.Xpos,'String',posx); set(handles.Ypos,'String',posy);

%If mouse over then update the immage

if ((115 < pos(1)) && (pos(1) < 125) && (7 < pos(2)) && (pos(2) < 11))
axes(handles.axes1);
imshow('condH.png')  
else 
 axes(handles.axes1);
imshow('cond.png')

 end

 if ((90 < pos(1)) && (pos(1) < 100) && (7 < pos(2)) && (pos(2) < 11))
 axes(handles.axes2);
 imshow('compH.png')  
 else
axes(handles.axes2);
 imshow('comp.png')  
 end

if ((80 < pos(1)) && (pos(1) < 90) && (7 < pos(2)) && (pos(2) < 11))
axes(handles.axes3);
imshow('evapH.png')  
else
 axes(handles.axes3);
 imshow('evap.png')  
 end

if ((90 < pos(1)) && (pos(1) < 100) && (2 < pos(2)) && (pos(2) < 5))
axes(handles.axes4);
imshow('expH.png')  
else
 axes(handles.axes4);
 imshow('exp.png')  
end

通常,在我通过将鼠标悬停在预定框上触发其中一个 if 语句之前,GUI 运行良好。然后 GUI 停止响应,直到 Matlab 重新启动后才会再次打开。

【问题讨论】:

    标签: user-interface matlab


    【解决方案1】:

    如果不查看您的整个代码,就很难判断 MATLAB 为何会崩溃。出于这个原因,我写了下面的简短示例。它说明了我将如何使用WindowButtonMotionFcn 回调编写一个模拟rollover effect 的GUI:

    function testRolloverGUI()
        %# prepare rollover image
        imgOff = imread('coins.png');
        imgOn = imcomplement(imgOff);
    
        %# setup figure
        hFig = figure('Resize','off', 'MenuBar','none', 'Color','w');
        set(hFig, 'WindowButtonMotionFcn',@figWindowButtonMotionFcn);
        hTxt = uicontrol('Style','text', 'String','(0,0)');
    
        %# setup axes
        NUM = 4;
        hAx = zeros(1,NUM);
        hImg = zeros(1,NUM);
        for k=1:NUM
            hAx(k) = subplot(2,2,k);
            hImg(k) = imagesc(imgOff, 'Parent',hAx(k));
        end
        colormap(gray)
        set(hAx, 'XTick',[], 'YTick',[], 'Box','on')
    
        %# get corner-points of each axis
        set(hAx, 'Units','pixels')
        axPos = cell2mat( get(hAx,'Position') );
        p = zeros(5,2,NUM);
        for k=1:NUM
            p(:,:,k) = bsxfun(@plus, axPos(k,1:2), ...
                [0 0; axPos(k,3) 0; axPos(k,3:4); 0 axPos(k,4); 0 0]);
        end
    
        %# callback function
        function figWindowButtonMotionFcn(hObj,ev)
            %# get mouse current position
            pos = get(hObj, 'CurrentPoint');
            set(hTxt, 'String',sprintf('(%g,%g)',pos))
    
            %# for each axis, determine if we are inside it
            for i=1:numel(hImg)
                if inpolygon(pos(1),pos(2), p(:,1,i),p(:,2,i))
                    set(hImg(i), 'CData',imgOn)
                    set(hAx(i), 'LineWidth',3, 'XColor','r', 'YColor','r')
                else
                    set(hImg(i), 'CData',imgOff)
                    set(hAx(i), 'LineWidth',1, 'XColor','k', 'YColor','k')
                end
            end
        end
    end
    


    编辑#2

    为了响应您的 cmets,我在 GUIDE 中重新创建了示例。以下是主要部分:

    %# --- Executes just before rollover is made visible.
    function rollover_OpeningFcn(hObject, eventdata, handles, varargin)
    
        %# Choose default command line output for rollover
        handles.output = hObject;
    
        %# allocate
        NUM = 4;
        imgOff = cell(1,NUM);
        imgOn = cell(1,NUM);
        hImg = zeros(1,NUM);
    
        %# read images
        imgOff{1} = imread('coins.png');
        imgOn{1} = imcomplement(imread('coins.png'));
        imgOff{2} = imread('coins.png');
        imgOn{2} = imcomplement(imread('coins.png'));
        imgOff{3} = imread('coins.png');
        imgOn{3} = imcomplement(imread('coins.png'));
        imgOff{4} = imread('coins.png');
        imgOn{4} = imcomplement(imread('coins.png'));
    
        %# setup axes
        hAx = [handles.axes1 handles.axes2 handles.axes3 handles.axes4];
        for i=1:NUM
            hImg(i) = imagesc(imgOff{i}, 'Parent',hAx(i));
        end
        colormap(hObject, 'gray')
        set(hAx, 'XTick',[], 'YTick',[], 'Box','on')
    
        %# make sure axes units match that of the figure
        set(hAx, 'Units',get(hObject, 'Units'))
    
        %# check axes parent container (figure or panel)
        hAxParents = cell2mat( get(hAx,'Parent') );
        idx = ismember(get(hAxParents,'Type'), 'uipanel');
        ppos = cell2mat( get(hAxParents(idx), 'Position') );
    
        %# adjust position relative to parent container
        axPos = cell2mat( get(hAx,'Position') );
        axPos(idx,1:2) = axPos(idx,1:2) + ppos(:,1:2);
    
        %# compute corner-points of each axis
        p = zeros(5,2,NUM);
        for k=1:NUM
            p(:,:,k) = bsxfun(@plus, axPos(k,1:2), ...
                [0 0; axPos(k,3) 0; axPos(k,3:4); 0 axPos(k,4); 0 0]);
        end
    
        %# store in handles structure
        handles.p = p;
        handles.hAx = hAx;
        handles.hImg = hImg;
        handles.imgOff = imgOff;
        handles.imgOn = imgOn;
    
        %# Update handles structure
        guidata(hObject, handles);
    
    
    %# --- Executes on mouse motion over figure - except title and menu.
    function figure1_WindowButtonMotionFcn(hObject, eventdata, handles)
    
        %# CurrentPoint
        pos = get(hObject,'CurrentPoint');
        set(handles.text1,'String',sprintf('(%g,%g)',pos));
    
        %# for each axis, determine if we are inside it
        for i=1:numel(handles.hImg)
            if inpolygon(pos(1),pos(2), handles.p(:,1,i),handles.p(:,2,i))
                set(handles.hImg(i), 'CData',handles.imgOn{i})
                set(handles.hAx(i), 'LineWidth',3, 'XColor','r', 'YColor','r')
            else
                set(handles.hImg(i), 'CData',handles.imgOff{i})
                set(handles.hAx(i), 'LineWidth',1, 'XColor','k', 'YColor','k')
            end
        end
    

    GUI 具有与以前基本相同的组件,除了轴包含在 uipanel 内(类似于您的 GUI 屏幕截图):

    需要注意的几点:

    • 由于我们的目标是将图形的CurrentPoint 与坐标轴位置进行比较,因此它们具有与图形相同的Units 非常重要,因此:set(hAx, 'Units',get(hObject, 'Units'))

      李>
    • 根据documentation,一个轴Position属性是相对于它的父容器的,因为四个轴在一个面板内,我们需要相应地调整它们的位置:axPos(idx,1:2) = axPos(idx,1:2) + ppos(:,1:2);

    【讨论】:

    • 好的。我不知道您是否想查看整个代码,但对于此示例代码,我将如何修改它以使用 GUIDE 预制轴和图形?
    • 而且它们是开放函数,因为同时拥有这两种类型是“非法的”
    • @CMacDady:应该类似:第一部分是我以编程方式设置图形和轴的位置。这可以使用 GUIDE 和属性检查器来完成。请注意,最好在图形的初始化函数中读取和存储一次图像。接下来,您将设置WindowButtonMotionFcn 回调,如上所示。简单地更新图像的CData 比像您正在做的那样从头开始重绘它更快。最后,我使用了INPOLYGON 函数,但如果你愿意,你可以保留你的测试......
    • 好的,回调。每次调用 WindowButtonMotionFcn 时,它都会通过 for 循环遍历每个区域。但是,您在一个矩阵中存储了 4 个子图,然后是属于子图的 4 个图像......我有预制轴我可以做类似 hAx(1) = axes1; hAx(2) = 轴2; ?
    • @CMacDady:绝对是的,那只是为了方便。在你的情况下,你可以这样做:hAx = [handles.axes1 handles.axes2 handles.axes3];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-02-20
    • 2013-11-11
    • 1970-01-01
    相关资源
    最近更新 更多