Фатальная ошибка от Matlab GUI - PullRequest
3 голосов
/ 28 июля 2011

Отредактированное сообщение

Это новые функции, которые я создал, используя ваш шаблон, чтобы выручить меня.Происходит то, что, хотя код работает нормально, поля «проверка на наличие курсора» расположены не поверх осей.На самом деле они очень далеко.Я использовал disp (axPos) один раз с set (hAx, 'Units', 'пиксели'), и один раз с этим закомментировал.Он отображал:

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

Это координаты ОРИГИНАЛА, а не координаты, отображаемые для «Текущей точки»

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

enter image description here Это хитбоксы с оригинальным кодом "set (hAx, 'Units', 'пикселей')"

Примечание * остальные находятся далеко от экрана в правом верхнем углу, или будет.

enter image description here Это хитбоксы с измененным кодом "set (hAx, 'Units', 'symbols')"

Примечание * Это точно то же самоеэто происходит, когда код закомментирован.

Проверено 2 августа.

.

.

.

Приложение Исходное сообщение

Я получаю эту ошибку после запуска моего графического интерфейса пользователя [Fatal Error]: -1: -1: Преждевременный конец файла.

Это происходит во время этого блока кода:

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, наведя курсор на предварительно определенное поле.Тогда графический интерфейс перестает отвечать и не открывается снова, пока не будет перезапущен Matlab.

1 Ответ

2 голосов
/ 28 июля 2011

Трудно сказать, почему происходит сбой MATLAB, не видя весь ваш код.По этой причине я написал короткий пример ниже.Это иллюстрирует, как я хотел бы написать GUI, который имитирует эффект ролловер с использованием обратного вызова WindowButtonMotionFcn :

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

screenshot


РЕДАКТИРОВАТЬ # 2

В ответ на ваши комментарии я воссоздал пример в 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):

GUIDE

Несколько замечаний:

  • Поскольку наша цель - сравнить CurrentPoint фигуры с положением осей, важно, чтобы ониимеют то же значение Units, что и на рисунке, таким образом: set(hAx, 'Units',get(hObject, 'Units'))

  • Согласно документации свойство оси Position относительно егородительский контейнер, и поскольку четыре оси находятся внутри панели, нам необходимо соответствующим образом отрегулировать их положения: axPos(idx,1:2) = axPos(idx,1:2) + ppos(:,1:2);

GUI_in_action

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...