Matlab: что-то вроде «относительной» позиции с помощью uicontrol / axis;сохранять фиксированные поля при изменении размера - PullRequest
7 голосов
/ 15 декабря 2011

У меня сейчас большая головная боль из-за того, что маленький графический интерфейс работает нормально, который создается не с помощью графического редактора, а программно! То, что у меня есть, выглядит примерно так:

hFig = figure();
set(hFig, 'Position', [300 200 500 400]);
plot((1:10).^2, '*-r');

% Größe des Plots so anpassen, dass links Platz für Buttons
ap = get(gca, 'TightInset');
fp = get(gcf, 'Position');
set(gca, 'Position', [160/fp(3), 30/fp(4), (fp(3)-180)/fp(3), (fp(4)-60)/fp(4)]);

uicontrol('Style', 'pushbutton', 'String', 'foo', 'Position', [15 fp(4)-60 110 30]); 
uicontrol('Style', 'pushbutton', 'String', 'bar', 'Position', [15 fp(4)-100 110 30]); 

Попробуйте изменить его размер: он не «выглядит» одинаково, что означает, что поля uicontrol не остаются в одном и том же относительном положении, а поля от оси до окна рисунка увеличиваются. Чего я хочу добиться:

Иметь окно фигуры с заданной позицией (x / y, ширина и высота) с графиком внутри. Сюжет будет иметь заголовок и метки для х и у. Сделайте график в виде высоты и ширины, чтобы TightInset плюс поле в каждом направлении определенного размера в пикселях (например, TightInset + 10px) размером с окно рисунка; за исключением того, чтобы оставить слева 150px свободного пространства, чтобы разместить несколько кнопок uicontrol, и оставить их в том же положении: это было бы то же самое, что и возможность задать положение сверху / слева (top = 20, left = 10) внизу / слева.

Большое спасибо!

Ответы [ 3 ]

5 голосов
/ 15 декабря 2011

Хорошо, наконец-то нашел рабочее решение, которое я хотел, чтобы оно было :-) Надеюсь, это будет полезно для кого-то заинтересованного в этом:

Основной файл сценария:

p = [300 300 1000 600];
fixedMargins = [250 0 0 0]; % [left, top, right, bottom]
f = figure('Position', p, 'Color', [0.9 0.9 0.9]);
plot(-10:10, (-10:10).^3, '*-r');
set(f, 'ResizeFcn', {@resizeCallback, gca, fixedMargins, {@myuiFunc, f, 40, 50}});

title('bla')
xlabel('foooooooooo')
ylabel('barrrrrrr')

Изменение размера функции обратного вызова:

% Need to pass the handle of the axis to modify (hAx) AND to pass the
% desired margins as second extra callback argument: 
% [left, top, right, bottom]!
function resizeCallback(hFig, ~, hAx, fixedMargins, func)    
    % Disable automatic rezising
    set(hAx, 'Units', 'pixels');

    % Figure-Size
    fp = get(hFig, 'Position');

    % Calculate Position of the axis
    margin = get(hAx, 'TightInset') * [-1 0 1 0; 0 -1 0 1; 0 0 1 0; 0 0 0 1];

    % Position to fill the figure minus the TightInset-Margin
    newPos = [0 0 fp(3:4)] - margin;

    % Change position based on margins
    newPos(1) = newPos(1) + fixedMargins(1);
    newPos(3) = newPos(3) - fixedMargins(1) - fixedMargins(3);
    newPos(2) = newPos(2) + fixedMargins(4);
    newPos(4) = newPos(4) - fixedMargins(2) - fixedMargins(4);

    % Set new position
    set(hAx, 'Position', newPos);

    % Call UI-Func
    if(nargin == 5)
        f = func{1};
        args = func(2:end);
        f(args{:});
    end
end

Вы можете передать любую функцию, которую хотите вызвать, при изменении размера окна рисунка, например, чтобы обновить что-либо на рисунке.В моем примере это myuiFunc (), которая выглядит следующим образом:

function myuiFunc(hFig, left, top)
    persistent handles;

    if(~isempty(handles))
        delete(handles);
        handles = [];
    end

    fp = get(hFig, 'Position');
    h1 = uicontrol('Style', 'pushbutton', 'String', 'Foo','Position', [left fp(4)-top 100 35]);
    h2 = uicontrol('Style', 'pushbutton', 'String', 'Bar','Position', [left fp(4)-top-50 100 35]);
    handles = [h1 h2];
end

Мне нравится :) Надеюсь, вы тоже!

Редактировать : редактировать не нужнофункция resizeCallback!Должно работать, если вы просто передаете желаемые поля и, если хотите, дополнительно описатель функции с аргументами, которые будут вызываться для каждого изменения размера!

1 голос
/ 31 июля 2014

uicontrol('Style', 'pushbutton', 'String', 'foo', 'Units','normalized','Position', [0.90 0.05 0.08 0.08] );

1 голос
/ 19 декабря 2011

Вы также можете использовать «Нормализованные» единицы.

...