• Регистрация
alextip
alextip +46.13
н/д

Как лучше экспортировать данные из appdesigner для последующего использования

21.05.2020

Здравствуйте! Создал приложение в appdesigner. В нем вводятся из графического интерфейса данные и сохраняются внутри приложения в структуре, где поля структуры могут представлять собой строковые переменные, числовые массивы и таблицы. Как лучше всего эти данные экспортировать в файл, чтобы потом его повторно исопользовать в приложении и не вводить все заново? Или чтобы создать несколько вариантов входных данных и загружать нужный?

Экспорт в текстовый файл кажется сомнительным, так как потом нужно будет выделять из него все поля структуры обратно, а они могут иметь разные размеры. Муторно это. Функцию, которая бы экспортировала структуру в матлабе не нашел. Mat-файл отлично подходит, но внутри appdesigner он не может использоваться. Да и потом, даже если это вдруг возможно, нужно чтоб приложение работало без привязки к Matlab, standalone так сказать.

Может что посоветуете?

Теги

    21.05.2020

    Лучший ответ

    • kurguz+270.00
      23.05.2020 12:00

      Ага, теперь понятно, вот такой синтаксис сработает, здесь данные из mat-файла записываются в переменную:

      app.mydata = load("test.mat", "x1", "x2");

      Вот в справке есть строчка, в которой говорится, что так можно писать:

      Ну и чтобы загруженные данные хранились между вызовами вашей функции, создайте property, как вы уже сделали с иксами:

      properties (Access = private)
         x1 % Description
         mydata
      end

      ... или можно хранить данные в поле UserData почти любого ui - элемента, например так:

      app.EditField.UserData = load("test.mat", "x1", "x2");

    Ответы

    • kurguz
      kurguz+270.00
      22.05.2020 10:56

      Странно, что с mat-файлом проблемы, можете показать?

      Как вариант: структуры хорошо конвертируются в текст в JSON-формат и обратно, для работы с ним есть jsonencode и jsondecode.

      • alextip
        alextip+46.13
        22.05.2020 20:09

        mat-файл считывается в рабочее пространство Matlab, а когда приложение работает без Matlab, то считывать его некуда.

        • kurguz
          kurguz+270.00
          22.05.2020 20:18

          Ну вы же где-то храните переменные в приложении, вот туда и загружайте, это и будет ваше рабочее пространство. Я без демонстрации не могу представить, что тут может пойти не так... 

          • alextip
            alextip+46.13
            22.05.2020 20:32

            ОК, попробую еще раз, что не получится покажу.

        • alextip
          alextip+46.13
          22.05.2020 20:14

          Пока решил вопрос через преобразование в таблицу со строковыми переменными и обратно. Чтение-запись через writetable и readtable. С JSON-форматом дела не имел, надо будет попробовать, спасибо.

          Может с мат-файлом я перемудрил чего, попробую еще разок.

          • alextip
            alextip+46.13
            23.05.2020 17:13

            При попытке воспользоваться командами save и load выдает ошибки:

            Warning: Unable to save App Designer app object. Save not supported for matlab.apps.AppBase objects.

            Unable to load App Designer app object. Load not supported for matlab.apps.AppBase objects.

            • kurguz
              kurguz+270.00
              23.05.2020 17:19

              Я рассчитывал увидеть ваш код, который неправильно работает, и возможно его расположение в приложении.

            • alextip
              alextip+46.13
              23.05.2020 19:26

              Вот, например:

              properties (Access = private)
                 x1 % Description
              end

              properties (Access = public)
                 x2 % Description
              end

              % Callbacks that handle component events
              methods (Access = private)

              % Code that executes after component creation
                 function startupFcn(app)
                    app.x1 = 1;
                    app.x2 = 2;
                    save test.mat;
                    app.x2 = 3;
                    app.x1 = 4;
                    load test.mat x1 x2;
                    app.EditField.Value = app.x1;
                    app.EditField2.Value = app.x2;
                 end
              end

              Окно тестового приложения

              В окошке видно, что ничего не загрузилось.

              • alextip
                alextip+46.13
                23.05.2020 19:30

                load test.mat x1 x2;

                можно поменять на

                load test.mat app.x1 app.x2;

                или на 

                load test.mat;

                Загрузки все равно нет.

                • kurguz
                  kurguz+270.00
                  23.05.2020 20:11

                  Ага, теперь понятно, вот такой синтаксис сработает, здесь данные из mat-файла записываются в переменную:

                  app.mydata = load("test.mat", "x1", "x2");

                  Вот в справке есть строчка, в которой говорится, что так можно писать:

                  Ну и чтобы загруженные данные хранились между вызовами вашей функции, создайте property, как вы уже сделали с иксами:

                  properties (Access = private)
                     x1 % Description
                     mydata
                  end

                  ... или можно хранить данные в поле UserData почти любого ui - элемента, например так:

                  app.EditField.UserData = load("test.mat", "x1", "x2");
                  • alextip
                    alextip+46.13
                    23.05.2020 20:48

                    Ух ты!

                    • alextip
                      alextip+46.13
                      23.05.2020 21:00

                      Только не понял, как потом из app.mydata извлечь нужные данные. Например, те же x1 и x2?

                      • kurguz
                        kurguz+270.00
                        23.05.2020 22:34

                        Обращайтесь к ним, как к полям структуры:

                        app.mydata.x1
                      • alextip
                        alextip+46.13
                        24.05.2020 19:05

                        Почему-то не получается.

                         

                        properties (Access = private)
                           x1; % Description
                           x2 % Description
                           tempdata; % Description

                        end

                        % Callbacks that handle component events
                           methods (Access = private)

                        % Code that executes after component creation
                           function startupFcn(app)
                              app.x1 = 1;
                              app.x2 = 2;
                              save test.mat;
                              app.x2 = 3;
                              app.x1 = 4;
                              app.tempdata=load("test.mat", "x1", "x2");
                              app.EditField.Value = app.x1;
                              app.EditField2.Value = app.x2;
                              app.TextArea.Value = string(app.tempdata.x1);
                           end
                        end

                        Выдает

                        Reference to non-existent field 'x1'.

                        Error in testApp/startupFcn (line 35)
                        app.TextArea.Value = string(app.tempdata.x1);

                        Error in testApp (line 98)
                        runStartupFcn(app, @startupFcn)

                        А если открыть test.mat в Matlab, ничего кроме объекта app внутри нет.

                        В окошке видно, что переменные не загрузились.

                        • kurguz
                          kurguz+270.00
                          25.05.2020 16:42

                          Вы неправильно используете функцию save. Попробуйте посмотреть в справке.

                        • alextip
                          alextip+46.13
                          25.05.2020 21:40

                          properties (Access = private)
                             x1; % Description
                             x2 % Description
                             tempdata; % Description

                          end

                          % Callbacks that handle component events
                          methods (Access = private)

                          % Code that executes after component creation
                             function startupFcn(app)
                                      app.x1 = 1;

                                      app.x2 = 2;

                                      y1 = app.x1;

                                      y2 = app.x2;

                                      save('myFile.mat','y1','y2');

                                      app.x1 = 3; %До загрузки

                                      app.x2 = 4;

                                      y1 = 5;

                                      y2 = 6;

                                      app.tempdata=load("myFile.mat",'y1','y2');

                                      app.x1 = app.tempdata.y1; %После загрузки

                                      app.x2 = app.tempdata.y2;

                                      app.EditField.Value = app.x1;

                                      app.EditField2.Value = app.x2;

                                      app.TextArea.Value = string(app.tempdata.y1) + " " + string(app.tempdata.y2);

                             end
                          end

                           

                          Вот в таком варианте заработало. Только как это понять из справки - неведомо. Ничего про то, что к публичным и частным переменным нельзя обращаться командой save я не нашел.  Для меня это был логичный вариант.