Вопрос по TabGroup

Форум, посвященный общим вопросам, связанным с MATLAB

Модератор: Admin

Sandro
Пользователь
Сообщения: 105
Зарегистрирован: Ср сен 22, 2004 4:49 pm

Вопрос по TabGroup

Сообщение Sandro » Вт апр 10, 2018 12:29 pm

App Designer.
На фигуре создается TabGroup и несколько вкладок. Пытаюсь сделать, чтобы при переключении между вкладками выполнялась функция selecTab:

app.hTabGImg = uitabgroup(app.hFImages, 'SelectionChangedFcn',@selecTab);

сам код записан в функции selecTab как Private Function

function selecTab(app)
% -------------------------------------------------------------
hTab = uitab(app.hTabGImg);
......
.....
% -------------------------------------------------------------
end

Но при переключении вкладок выдается сообщение:

Undefined function 'selecTab' for input arguments of type 'matlab.ui.container.TabGroup'.
Error while evaluating TabGroup SelectionChangedFcn.

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Ср апр 11, 2018 2:44 pm

@app.selecTab т.к. обращение идет к конкретному экземпляру класса.

Sandro
Пользователь
Сообщения: 105
Зарегистрирован: Ср сен 22, 2004 4:49 pm

Re: Вопрос по TabGroup

Сообщение Sandro » Ср апр 11, 2018 4:24 pm

Пробывал:

Код: Выделить всё

app.hTabGImg = uitabgroup(app.hFImages, 'SelectionChangedFcn',@app.selecTab);



Код: Выделить всё

function selecTab(app)
% -------------------------------------------------------------
hTab = uitab(app.hTabGImg);
......
.....
% -------------------------------------------------------------
end


Выдается ошибка:
Error using AllSkyExplorer/selecTab
Too many input arguments.

Error in AllSkyExplorer>@(varargin)app.selecTab(varargin{:}) (line 262)
app.hTabGImg = uitabgroup(app.hFImages, 'SelectionChangedFcn',@app.selecTab); % На Фигуре Создается
группа для вкладок с изображениями

Error while evaluating TabGroup SelectionChangedFcn.

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Чт апр 12, 2018 5:39 pm

есть принципиальная ошибка в объявлении callback у него не один аргумент, как вы думаете, а три!
Вот рабочий примерчик. Надо сохранить под тем же именем (m - файл), что и класс. Можно проинсталлировать, также как и приложение

Код: Выделить всё

classdef (ConstructOnLoad = true, HandleCompatible = true) TTable < handle
    properties (Access = private, Constant = true,  Hidden = true)
        DEFINE_WND_HEIGHT = 240;
        DEFINE_WND_WIDTH = 320;
    end
   
    properties (Access = private, Hidden = true)
        HWND;       %figure
        HTabCTRL;   %uitabgroup
        HTab_1;       %uitab
        HTab_2;       %uitab
        HTab_3;       %uitab
        HTab_4;       %uitab
        HTab_5;       %uitab
       
        HSelectedTab;
       
        screen_rect;
        window_rect;
    end
   
    properties (Access = public, Dependent = true)
        Width;
        Height;       
    end
   
    methods
        function value = get.Width(hObject)
            value = hObject.window_rect(3);
        end
       
        function set.Width(hObject, value)
            hObject.CalcWindowRect(hObject.window_rect(4), value);
            set(hObject.HWND, 'Position', hObject.window_rect);
        end
       
        function value = get.Height(hObject)
            value = hObject.window_rect(4);
        end
       
        function set.Height(hObject, value)
            hObject.CalcWindowRect(value, hObject.window_rect(3));
            set(hObject.HWND, 'Position', hObject.window_rect);
        end
    end
       
    methods (Access = public)
       
        function hObject = TTable(width, height)
            src = get(0);
            hObject.screen_rect = src.ScreenSize;   
           
            if (nargin ~= 2)
                width = hObject.DEFINE_WND_WIDTH;
                height = hObject.DEFINE_WND_HEIGHT;
            end
           
            hObject.CalcWindowRect(height, width);
           
            hObject.HWND = figure(...
                'NumberTitle', 'off',...
                'DockControls', 'off',...
                'MenuBar', 'none',...
                'Resize', 'off',...
                'Position', hObject.window_rect);       
       
           hObject.HTabCTRL = uitabgroup(...
               hObject.HWND,...
               'SelectionChangedFcn',...
               @hObject.selectTab);
           
           hObject.HTab_1 = uitab(hObject.HTabCTRL, 'Title', 'tab 1');           
           hObject.HTab_2 = uitab(hObject.HTabCTRL, 'Title', 'tab 2');           
           hObject.HTab_3 = uitab(hObject.HTabCTRL, 'Title', 'tab 3');           
           hObject.HTab_4 = uitab(hObject.HTabCTRL, 'Title', 'tab 4');           
           hObject.HTab_5 = uitab(hObject.HTabCTRL, 'Title', 'tab 5');
           
        end     
    end
   
    methods (Access = private)
        function CalcWindowRect(hObject, height, width)
            hObject.window_rect = [...
                fix((hObject.screen_rect(3)- width)/2),...
                fix((hObject.screen_rect(4)- height)/2),...
                width,...
                height];
        end
       
        function selectTab(hObject, src, event)
            hObject.HSelectedTab = src.SelectedTab;
            set(hObject.HWND,...
                'Name', ['selected is ' src.SelectedTab.Title]);
        end
    end
end


А вот, пример того, что будет в рабочем окне при его вызове из него родимого

Код: Выделить всё

>> f = TTable

f =

  TTable with properties:

     Width: 320
    Height: 240

>> f.Width

ans =

   320

>> f.Width = 1000

f =

  TTable with properties:

     Width: 1000
    Height: 240

>>
Последний раз редактировалось maria_kipke Пт апр 13, 2018 10:21 am, всего редактировалось 1 раз.

Sandro
Пользователь
Сообщения: 105
Зарегистрирован: Ср сен 22, 2004 4:49 pm

Re: Вопрос по TabGroup

Сообщение Sandro » Пт апр 13, 2018 9:34 am

Совершенно верно. Я об этом прочитал в "Add UI Components to App Designer Programmatically":
Write the callback function for the component as a private helper function. The function must have app, src, and event as the first three arguments.
(https://www.mathworks.com/help/matlab/c ... cally.html)

Но я часто ориентировался на приводимые примеры, а там от одного до трех, а иногда и вообще без аргументов!

Спасибо!

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Пт апр 13, 2018 9:44 am

Речь идет о том, что стандартные Callback, описываются только так, и хоть убейся. К объекту таймер (реализует идею многопоточности), кажется можно написать callback с произвольным количеством входных аргументов.

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Пт апр 13, 2018 10:39 am

Кстати, подправила код, конечно же функции callback должны находиться в приватной секции. Но здесь есть лирическое отступление: если в последствии не стоит задача переноса кода на другую языковую платформу, то иногда удобно пользоваться вложенными функциями. В том случае, когда известно, что данная функция вызывается только из определенного места, или когда приходиться кучу переменных тащить во входные параметры, можно поступить так:

Код: Выделить всё

        function hObject = TTable(width, height)
            src = get(0);
            hObject.screen_rect = src.ScreenSize;   
           
            if (nargin ~= 2)
                width = hObject.DEFINE_WND_WIDTH;
                height = hObject.DEFINE_WND_HEIGHT;
            end
           
            hObject.CalcWindowRect(height, width);
           
            hObject.HWND = figure(...
                'NumberTitle', 'off',...
                'DockControls', 'off',...
                'MenuBar', 'none',...
                'Resize', 'off',...
                'Position', hObject.window_rect); 
           
            hObject.HTabCTRL = uitabgroup(...
                hObject.HWND,...
                'SelectionChangedFcn',...
                @selectTab);
           
            hObject.HTab_1 = uitab(hObject.HTabCTRL, 'Title', 'tab 1');           
            hObject.HTab_2 = uitab(hObject.HTabCTRL, 'Title', 'tab 2');           
            hObject.HTab_3 = uitab(hObject.HTabCTRL, 'Title', 'tab 3');           
            hObject.HTab_4 = uitab(hObject.HTabCTRL, 'Title', 'tab 4');           
            hObject.HTab_5 = uitab(hObject.HTabCTRL, 'Title', 'tab 5');
           
            function selectTab(hObject, src, event)
                hObject.HSelectedTab = src.SelectedTab;
                set(hObject.HWND,...
                    'Name', ['selected is ' src.SelectedTab.Title]);
            end
        end

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Пт апр 13, 2018 11:09 am

В принципе, если Callback не нужна информация, хранящаяся в членах класса, то он может быть объявлен статическим методом класса (ну к примеру TImage), да еще и публичным, да еще содержать рекурсивный вызов:

Код: Выделить всё

methods (Access = public, Static = true)
    function image_Callback(src, event)
        color = [1.0, 0.2, 0.5];  %любой
        hAxes = src.Parent;
   
        delete(findobj(hAxes, 'Color', color));
        hHint = findobj(hAxes.Parent, 'Tag', 'hHint');
        set(hHint, 'Visible', 'off');
   
        if event.Button == 1
            x = event.IntersectionPoint(1);
            y = event.IntersectionPoint(2);
       
            plot([x x], hAxes.YLim,...
                 'Color', color,...
                 'ButtonDownFcn', @TImage.image_Callback);
       
             plot(hAxes.XLim, [y y],...
                 'Color', color,...
                 'ButtonDownFcn', @TImage.image_Callback);
         end
    end
end


Что это дает: можете пользоваться данным методом, где заблагорассудится, не создавая экземпляра класса, считая TImage за name space
imagesc(s, 'NextPlot', 'add', 'ButtonDownFcn', @TImage.image_Callback)

Sandro
Пользователь
Сообщения: 105
Зарегистрирован: Ср сен 22, 2004 4:49 pm

Re: Вопрос по TabGroup

Сообщение Sandro » Пт апр 13, 2018 9:20 pm

Спасибо! Постараюсь понять как это можно "имплиментировать" :D

maria_kipke
Пользователь
Сообщения: 76
Зарегистрирован: Чт окт 05, 2017 4:37 pm

Re: Вопрос по TabGroup

Сообщение maria_kipke » Пт апр 13, 2018 10:25 pm

Ну, послали - так, послали! Еще, и словом каким... :D
Пы.Сы: последний пример можно кастрировать до отдельной функции в отдельном файле (то бишь, убрать строку про методы и один end в конце, а также обращение к экземпляру классу в рекурсиве), и потренироваться на произвольном изображении. Это рожает перекрестье по левому (кажется, кнопка номер один) клику мыши на изображении, а рекурсив, для того случая, когда клик попадает на порожденную линию...объекты изображения и линий, суть - разные штуки со своими событиями.

Sandro
Пользователь
Сообщения: 105
Зарегистрирован: Ср сен 22, 2004 4:49 pm

Re: Вопрос по TabGroup

Сообщение Sandro » Вс апр 15, 2018 1:52 pm

Буду думать ... :shock:
У меня слабость на входящие письма - отвечать на них, даже если ответа не нужно. :D