4

How should I go about to convert (manually) code created by Matlab GUIDE GUI, to use Octave's UI Components?

Stuff like this:

gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
               'gui_Singleton',  gui_Singleton, ...
               'gui_OpeningFcn', @Mat_to_Octave_OpeningFcn, ...
               'gui_OutputFcn',  @Mat_to_Octave_OutputFcn, ...
               'gui_LayoutFcn',  [] , ...
               'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

etc. etc.

  1. Where can I find a comprehensive list of elements that I need to replace?

  2. How do I create the equivalent of the GUIDE callback function for Octave UI elements and can I make a single callback function for all the elements? Perhaps there's a difference here between the two.

  3. Is the GUID GUI code open, or open source? It surely seems so here.

  4. Is the UI layout that was set by the user in the GUIDE accessible? i.e Do we know where the button's width and text color settings are saved?

  5. Is there a comprehensive list somewhere? If so, where? Are all or at least most of the elements from GUIDE available in UI Components? How can I check this?

  6. Is there anything I left out before starting the task?

pashute
  • 3,965
  • 3
  • 38
  • 65
  • Not sure where to start with this. The syntax to create UI elements in matlab should be the same as octave. GUIDE is a graphical 'tool' matlab uses to help novice users, but otherwise all it should do is generate the relevant code which should for the most part be identical in octave. It is most certainly not 'open source' let alone copyleft; I don't think that link you provided has anything to do with it. I'm not sure what the above code is supposed to do. The various properties (e.g. width, color) are part of the generated object, and can be queried using the standard get / set functions. – Tasos Papastylianou Nov 16 '17 at 16:29
  • Thank you. So GUIDE actually creates code that uses "UI Elements", and these are the same for Octave? I don't think so. The Octave UI Elements were added late in development, and the current (2017) Octave versions fail to recognize the pages created by GUIDE. Maybe I'm wrong. I have limited experience porting projects from Matlab ot Octave. – pashute Nov 19 '17 at 07:59
  • I no longer have access to Matlab to test this, but in general yes Matlab and Octave GUI code should be mostly compatible. One small catch is that Octave is a bit unhappy about callback functions defined as nested functions for the time being; I believe most Matlab code makes use of nested functions in that way, so that might be the bug you're experiencing. See https://stackoverflow.com/q/40570494/4183191 and https://stackoverflow.com/q/43519040/4183191 for examples of a simple GUI in both languages, particularly Andy's example in the second question. These also address callback function use. – Tasos Papastylianou Nov 20 '17 at 10:19
  • so @TasosPapastylianou please post that as the answer and I'll accept. – pashute Nov 22 '17 at 13:14

1 Answers1

3

For the most part, GUI creation on octave is identical to matlab. GUI-creation is a relatively new addition to octave, so expect a couple of the more recent additions in the matlab family to have not yet made it into octave, but for the most part, matlab code implementing a GUI application should work on octave with no or very little need for tweaking. Here are the respective manual entries for matlab and octave; you will notice that the core functions are identical.

One important 'catch' is that octave does not support handles to nested functions for the time being (this might change later). For example, consider the following matlab code implementing a simple GUI with a slider affecting a plot (taken from this answer).

%%%%%% In file myplot.m %%%%%
function myplot

  %% Create initial figure and spiral plot
  figure;  axes ('position', [0.1, 0.3, 0.8, 0.6]);
  t = linspace (0, 8*pi, 100);  x = t .* cos(t);  y = t .* sin(t);
  plot (x, y);  axis ([-100, 100, -100, 100]);

  %% Add ui 'slider' element      
  hslider = uicontrol (                    ...
         'style', 'slider',                ...
         'Units', 'normalized',            ...
         'position', [0.1, 0.1, 0.8, 0.1], ...
         'min', 1,                         ...
         'max', 50,                        ...
         'value', 10,                      ...
         'callback', {@plotstuff}          ...
       );

  %% Callback function called by slider event
  function plotstuff (h, event)
    n = get (h, 'value');
    x = n * t .* cos(t);  y = n * t .* sin(t);
    plot (x, y);  axis ([-100, 100, -100, 100]);
  end
end

If you try running this on octave, you will get the following error message:

>> myplot
error: handles to nested functions are not yet supported
error: called from myplot at line 10 column 11

Converting the nested function into an independent function or subfunction resolves this (as demonstrated in this answer).

As for GUIDE, while octave does not have a similar "user-friendly" graphical tool for GUI-app creation yet, at the end of the day, all GUIDE does is produce appropriate underlying code for UI-element creation, which in theory should be compatible with octave. Having said that, it's worth reading up exactly what files GUIDE creates, namely a '.fig' file loading up the figure element, and a 'functions' file holding callbacks and actual code, etc. So, "running" a GUIDE generated file in octave will probably involve 'loading' the figure first. Also, in practice, GUIDE may make use of nested functions for callbacks, so the code might take a bit of tweaking to convert these into suitable subfunctions to get it working on octave.

Having said that, GUIDE really is more for people who like to avoid 'actual' code, but in fact, coding the GUI in matlab / octave directly is probably far more straightforward, once you get familiar with how get / set commands work for manipulating ui-element properties. And if you're after GUI solutions that work for both octave and matlab, I would certainly advise going down this route, and sticking to subfunctions instead of nested functions.

To answer the remaining two questions which haven't been covered by the above:

  • No, GUIDE is not open source (let alone free software). It is proprietary code from Mathworks which uses their licence. In particular, in theory there might be licencing issues with using GUIDE-generated code with octave, but I don't know for sure.

  • GUIDE generates a .fig file directly. This is a binary file that can be loaded onto matlab (and in theory, octave). With GUIDE, there is no other 'source' file detailing the uielements and their properties that were used to create this figure. Having said that, in matlab, once the figure is loaded, you can export 'source code' from the figure's graphical menu, that re-creates this figure, if desired. However, this may not be the most human-friendly code to look at. This is one of the reasons to prefer the programmatic approach over GUIDE: you have clean, clear source code, which details the properties of the uielements programmatically, rather than having to fish them out by loading a figure and searching through its properties.

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • 1
    You fully answered my questions, although for the record: We have hundreds of thousands of lines of code many of them done with GUIDE and wanted to port them without going into the actual code and writing it a second time. – pashute Nov 25 '17 at 23:39
  • Ah. Thanks, that sheds a bit more light to your particular situation. I think, on one extreme, it's highly unlikely you'll get GUIDE generated files to "just work" on octave without some tweaking, on the other hand it should be a matter of tweaking rather than rewriting entirely. It will probably be worth going through the procedure outlined above with the original files in matlab to generate scripts from .fig files, and tweak those (e.g. to convert nested functions to subfunctions) appropriately. If you have particular files that fail, you could always ask such a specific use-case here. – Tasos Papastylianou Nov 26 '17 at 14:56
  • The code in my question is typical of this. Created by GUIDE – pashute Nov 27 '17 at 19:31
  • Dear @pashute I looked into this a bit more and it appears I'm wrong on one point. According to the `Note` at the bottom of [this section](https://uk.mathworks.com/help/matlab/creating_guis/about-the-simple-guide-gui-example.html#bt421os-1): "Do not attempt to run your app by opening its FIG-file outside of GUIDE. If you do so, the figure opens and appears ready to use, but the UI does not initialize and the callbacks do not function.". In matlab you're supposed to use the `guide` function instead. Therefore presumably for octave only the 'export', rather than the 'loading' method can be used. – Tasos Papastylianou Nov 28 '17 at 10:55
  • Some more useful links on the matter: http://matlab.izmiran.ru/help/techdoc/creating_guis/callbacks4.html https://undocumentedmatlab.com/blog/fig-files-format (and more generally for nice GUI examples without GUIDE https://uk.mathworks.com/matlabcentral/fileexchange/24861-41-complete-gui-examples although I know this doesn't help with your specific problem ). Unfortunately I don't have matlab at the moment to test running a guide generated file on octave, and can't find a sample file online. If you'd like to attach an example of a pair of .fig / .m files here, I'll have a look out of interest. – Tasos Papastylianou Nov 28 '17 at 11:01
  • if you do so, please also attach an "exported" version of the .fig file (i.e. run it by doing `guide myGUI.fig` and then select File -> Export or whatever it's called (it could be called "convert to source code" or something). – Tasos Papastylianou Nov 28 '17 at 11:04
  • Thank you!! that is very useful – pashute Nov 29 '17 at 13:01