Returning data from uibutton callback

18 visualizzazioni (ultimi 30 giorni)
James Browne
James Browne il 18 Mag 2024
Modificato: Stephen23 il 20 Mag 2024
Hi,
I want to create a script that lets me add rows to a uitable with a ui buttom. My script mostly does what I want, except that it doesn't store the inputed values when I edit the table, nor does it return the eddited table back to memory to be used later. Is anyone able to point me in the right direction?
clc
Support = [0];
Type = {false};
t = table(Support,Type);
fig = uifigure;
uit = uitable(fig,"Data",t);
btn = uibutton(fig,"Text","Add Row","Position", [400 100 100 50],"ButtonPushedFcn",@(src,event) buttonCallback(t,fig));
uit.ColumnEditable = true;
function buttonCallback(t,fig)
Support = 0;
Type = {false};
addrow = table(Support,Type);
t = [t;addrow];
uit = uitable(fig,"Data",t);
uit.ColumnEditable = true;
btn = uibutton(fig,"Text","Add Row","Position", [400 100 100 50],"ButtonPushedFcn",@(src,event) buttonCallback(t,fig));
end
Error using matlab.internal.capability.Capability.require (line 94)
This functionality is not available on remote platforms.

Error in matlab.ui.internal.uifigureImpl (line 32)
Capability.require(Capability.WebWindow);

Error in uifigure (line 34)
window = matlab.ui.internal.uifigureImpl(varargin{:});
  1 Commento
Stephen23
Stephen23 il 18 Mag 2024
"Is anyone able to point me in the right direction?"
That is not how to write code for a GUI.
You are still writing linear code: first A executes, then B, then C, etc. until your script reaches the end.
But GUIs are fundamentally asynchronous code, and thinking in terms of linear code is a major hinderance to writing a GUI (i.e. you need to change how you think about code being executed). Note that in general GUI events will occur in no particular sequence. It takes a while to change how you think about code, but here are a few tips:
  • write functions (not scripts).
  • the GUI calls your functions (not a script calls a GUI)
  • in other words: callback functions are triggered by GUI events
  • share data properly within the GUI (i.e. avoid evil ASSIGNIN et al).
Take a look on FEX to find plenty of GUI examples which show how to perform basic actions (like reading a button status), they are often a good way to see how tasks should be achieved:

Accedi per commentare.

Risposte (1)

Voss
Voss il 18 Mag 2024
An easy way to make the callback update the value of t is to nest the callback function inside the main function (which requires using a function - rather than a script - for the main function). Nested functions can access and modify variables in the workspaces of functions that contain them.
For example, in the code below, the variable t is used in both the main_GUI function and the buttonCallback function (which is nested in main_GUI), which means the two functions' workspaces share the variable t. Therefore, when buttonCallback changes t, t is modified in both functions' workspaces (since they share the variable):
function main_GUI()
Support = 0;
Type = {false};
t = table(Support,Type);
fig = uifigure;
uit = uitable(fig,"Data",t);
btn = uibutton(fig,"Text","Add Row","Position", [400 100 100 50],"ButtonPushedFcn",@(src,event) buttonCallback());
uit.ColumnEditable = true;
function buttonCallback()
newSupport = 0;
newType = {false};
addrow = {newSupport,newType};
uit.Data = [uit.Data; addrow]; % add a row to the uitable
t = uit.Data; % update t
end
end
  3 Commenti
Voss
Voss il 19 Mag 2024
Modificato: Voss il 20 Mag 2024
When main_GUI runs, as soon as it is done doing what it does, which is to create the table and the button, it returns, so the value of t returned is the initial value.
If you want main_GUI to wait before returning so that the use can interact with the table and/or button, you'll need a uiwait or waitfor command. And you'll need to decide the condition(s) for returning, e.g., have another button that says "Done" or similar whose callback sets a flag letting the program know the user is ready for main_GUI to return.
Stephen23
Stephen23 il 19 Mag 2024
Modificato: Stephen23 il 20 Mag 2024
@James Browne: you can use WAITFOR:
For example, at the end of your main GUI code:
waitfor(fig)
The function (and your data) then returns when the figure is deleted. This is a simple, efficient, and reliable approach to including an asynchronous GUI within some linear code.

Accedi per commentare.

Categorie

Scopri di più su Develop uifigure-Based Apps in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by