Обновление списка и изменения переменной на старое значение в конце функции в MATLAB GUI - PullRequest
0 голосов
/ 08 января 2011

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

У меня есть 2 проблемы:

  1. Хотя обратный вызов для кнопки действительно действительно удаляет запись из массива x, после завершения обратного вызова массив x возвращается к исходному массиву x (таким образом, значение каким-то образом восстанавливается).

  2. Я пытаюсь использовать «drawnow», чтобы обновить список, чтобы отразить текущий массив x (который был изменен, по крайней мере, там, где drawnow выдается ниже).Ничего не меняется, хотя.Как я могу обновить список с новыми значениями массива x?

---------------- Код GUI --------

function testgui
clear; close all;
% Create the data
x = (10:20)'; % example data

% Create a figure
f = figure('Name', 'GUI Test',...
  'NumberTitle', 'off',...
  'MenuBar', 'none',...
  'Units', 'pixels',...
  'Position', [100 100 700 800],...
  'Visible', 'off');

% Create a set of axes
a = axes('Parent', f,...
  'Units', 'pixels',...
  'Position', [230 50 450 700]);

% Create a pushbutton for modifying x array
pb_x = uicontrol('Style', 'pushbutton', ...
  'Parent', f,...
  'String', 'Delete Selection',...
  'Units', 'pixels',...
  'Position', [50 7 100 35],...
  'Callback', @pb_change_x);

plot(x,'bo'); % graph
xlabel('Index Number'); ylabel('Variable x');

% Create a listbox to hold the x values
y=strtrim(cellstr(num2str(x)));
lb = uicontrol('Style', 'listbox',...
  'Parent', f,...
  'String', y,...
  'Units', 'pixels',...
  'Position', [50 50 100 700],...
  'Callback', @list_change);

set(f,'Visible','on')


function list_change(varargin)
    % Runs when the selection in listbox is changed
    curIdx = get(lb,'Value');
    % Index the value
    curVal = str2double(cell2mat(y(curIdx)));

    % Get position of curVal in x
    posVal = find(ismember(x,curVal));

    % Clear all the children currently on the axes
    delete(get(a,'Children'))

    % Plot the one data point of interest
    plot(posVal,curVal,'bo','MarkerFaceColor','b','MarkerSize',10)
    xlabel('Index Number'); ylabel('Variable x');
    % Plot all the data
    hold on
    plot(x,'bo')
    hold off
end

function pb_change_x(varargin)
    % Runs when DUT <<< pushbutton is clicked
    % Obtain selected index
    curIdx = get(lb,'Value');
    % Index the value
    curVal = str2double(cell2mat(y(curIdx)));

    % Get position of curVal in x
    posVal = ismember(x,curVal);
x(posVal) = []; % HELP (why doesn't value stick when this function returns?)

    % Redraw figure (want listbox to update)
drawnow; % HELP (how to refresh listbox with current x array?)

    % Clear all the children currently on the axes
    delete(get(a,'Children'))

    % Plot all the data
    plot(x,'bo'); xlabel('Index Number'); ylabel('Variable x');
end

end 

Ответы [ 2 ]

1 голос
/ 09 января 2011

Кажется, вы уже исправили проблему.Тем не менее, я переписал ваш пример и попытался немного упростить его:

function testgui2()
    data = [1:11 ; 10:20]';          %'# data
    handles = [];

    %# create GUI
    handles.hFig = figure('Name','GUI Test', 'NumberTitle','off', ...
        'Units','pixels', 'Position',[100 100 700 800], ...
        'MenuBar','none', 'Visible','off');
    handles.hAx = axes('Parent',handles.hFig, ...
        'Units','pixels', 'Position',[230 50 450 700]);
    handles.hPB = uicontrol('Style','pushbutton', 'Parent',handles.hFig, ...
        'String','Delete Selection',...
        'Units','pixels', 'Position',[50 7 100 35],...
        'Callback',@button_callback);
    handles.hLB = uicontrol('Style','listbox', 'Parent',handles.hFig, ...
        'String',data(:,2), 'Value',1, ...
        'Units','pixels', 'Position',[50 50 100 700], ...
        'Callback',@listbox_callback);
    set(handles.hFig, 'Visible','on')

    %# plot data and highlighted point
    handles.hPlot = plot(data(:,1), data(:,2), 'bo');
    handles.hLine = line('XData',data(1,1), 'YData',data(1,2), ...
        'Marker','o', 'MarkerSize',10, 'Color','b', 'MarkerFaceColor','b');
    xlabel('Index Number'), ylabel('Variable x')
    set(handles.hAx, 'XLimMode','manual', 'YLimMode','manual')    %# fix limits

    %# callback function for button
    function button_callback(varargin)
        %# get current selection
        selected = get(handles.hLB, 'Value');
        if selected==0, return, end

        %# remove data point
        data(selected,:) = [];

        %# update the listbox
        set(handles.hLB, 'String',data(:,2))
        set(handles.hLB, 'Value',min(selected,size(data,1)))
        %# update plot
        set(handles.hPlot, 'XData',data(:,1), 'YData',data(:,2))
        listbox_callback()
    end

    %# callback function for listbox
    function listbox_callback(varargin)
        %# get current selection
        selected = get(handles.hLB, 'Value');
        if selected==0, selected = []; end

        %# update plot (highlighted point)
        set(handles.hLine, 'XData',data(selected,1), 'YData',data(selected,2))
    end

end
1 голос
/ 08 января 2011

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

В частности, ваша реализация отдельно сохраняет оба GUI«x» - ваш массив данных на графике, а «y» - массив ячеек со строками для имен списков для каждого элемента в «x».Когда вы создали свой список «lb», вы указали «y» в качестве атрибута «String».В этот момент список отдельно хранит свою собственную копию «y» независимо от ваших переменных «y» и «x».

Когда вы обновляете свой график, вы сбрасываете значение графического интерфейса «x», но, как вы обнаружили, вам также необходимо обновить атрибут «String» списка (его копию «y»).В этом случае выбранный способ кажется наиболее простым, но более общий подход состоит в том, чтобы повторить шаги, используемые для генерации y из x (после обновления x), а затем использовать set (lb, String)., у); "сбросить версию GUI 'y'.

Надеюсь, что это полезно!: -)

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