Trying to delete the previous data/line from a next button using matlab Gui

Hello everyone,
i have a little problem. I was able to code a "Next button" using app designer that have as aim to draw lines. I had the data coming from excel. I am able to draw each line by clicking on the next button. The only problem is that the previous data/line is not deleted. So instead of having one line, i will have 2 or more depending on how many times i click on the next button.
To illustrate it more, you can see the attached document. I am expecting to have just one LINE/BAND
the Next button code is below
uiconfirm(app.UIFigure,'Are You sure?','Confirm Close',...
'CloseFcn',@(src,event)mycallback(app,src,event));
app.exp_counter = app.exp_counter + 1;
v_or_h = app.v_or_h_array(app.exp_counter);
app.v_thick1 = app.v_thickness_1(app.exp_counter);
app.v_thick2 = app.v_thickness_2(app.exp_counter);
app.h_thick1 = app.h_thickness_1(app.exp_counter);
app.h_thick2 = app.h_thickness_2(app.exp_counter);
%Vertical line
if v_or_h == 0
app.region1 = patch(app.UIAxes, ...
[app.v_thick1 app.v_thick2 app.v_thick2 app.v_thick1], ...
[-10 -10 10 10],'r', ...
'FaceAlpha',1,...
'LineWidth',0.01, ...
'LineStyle','-','tag','region1');
%Horizontal line
elseif v_or_h == 1
app.region1 = patch(app.UIAxes,[-10 10 10 -10], ...
[app.h_thick1 app.h_thick1 app.h_thick2 app.h_thick2], ...
'r','FaceAlpha',1,...
'LineWidth',0.01, ...
'LineStyle','-','tag','region1');
end

3 commentaires

@Geoff Hayes and this is the last code.
function UIFigureWindowButtonMotion(app, event)
% Determine if mouse is within uiaxes
cp = app.UIFigure.CurrentPoint;
isInAxes = cp(1) >= app.UIAxes.Position(1) && ...
cp(1) <= sum(app.UIAxes.Position([1,3])) && ...
cp(2) >= app.UIAxes.Position(2) && ...
cp(2) <= sum(app.UIAxes.Position([2,4]));
if isInAxes
set(app.CurrentPositionEditField, 'Value',...
sprintf('%.2f, %.2f', app.UIAxes.CurrentPoint(1,1:2)))
else
set(app.CurrentPositionEditField, 'Value', '')
end
In the code, app.UIFigure is the property name inside app that has been given to the handle of a uifigure object, and app.UIAxes is the property name inside app that has been given to the handle of a uiaxes object (that is presumably inside UIFigure)
Each UIFigure has a property which records CurrentPoint (current point is recorded independently for each different figure). The units for the position defaults to pixels . This code assumes that whatever units is being used for the uifigure, the same units are being used for the axes.
CurrentPoint is in the order x and then y.
Each UIAxes has a property Position which records the location of the axes. The units for the position defaults to pixels. It is a vector which has the order bottom-left x, bottom-left y, width, height . So sum(app.UIAxes.Position([1,3])) is extracting the x of the bottom left and adding the width to determine where the right hand side is, and sum(app.UIAxes.Position([2,4])) is calculating where the top is. The code is therefore determining whether the current x position is within the left and right limits of the axes, and the current y position is within the bottom and top limits of the axes.
The code could be more robust. It could, for example, look at the figure CurrentAxes property instead of assuming a particular axes. It could avoid the assumption that the axes and the figure have the same Units.
The current source for overobj() also assumes that the units are pixels, but if you look at the source code it has the proper units conversion inside it, just commented out.
Thank you, Walter, so much for your explanation and the document you recommended!!!! now I know what it means and I solved my problem just now!!

Connectez-vous pour commenter.

 Réponse acceptée

@Franck paulin Ludovig pehn Mayo - If you only want one patch object to appear, then you will need to delete the old one before creating the new one since you overwrite the "old" patch handle with the new one:
app.region1 = patch(app.UIAxes, ...
You would need a line of code like
if ishandle(app.region1)
delete(app.region1);
end
called before you draw the new patch. Note that I'm assuming that the app object has an attribute named region1. If non such attribute exists, then you will need to handle that case.

11 commentaires

@Geoff Hayes Thank you for your reply.I did it that but there is another issue that came up.'Error using patch Vectors must be the same length.''
This is the main code. The previous code is the one i coded in the "NEXT BUTTON"
function startupFcn(app)
clc
% Read experiment data from a CSV file
% Plot patch on uiaxes
hold(app.UIAxes, 'on')
% region1 = patch(app.UIAxes,[-10 10 10 -10],[-5 -5 -4.4 -4.4],'r','FaceAlpha',1,...
%'LineWidth',0.01,'LineStyle','-','tag','region1');
load_folder = "C:\Users\Hp\Desktop\thesis\excel_data\";
load_name = "excel_data.xlsx";
load_addr = load_folder + load_name;
app.T = readtable(load_addr,'NumHeaderLines',1);
app.exp_counter = 1
app.v_thickness_1 = app.T.Var1;
app.v_thickness_2 = app.T.Var2;
app.h_thickness_1 = app.T.Var3;
app.h_thickness_2 = app.T.Var4;
app.amplitude_array = app.T.Var5;
app.v_or_h_array = app.T.Var6;
app.v_thick1 = app.v_thickness_1(app.exp_counter);
app.v_thick2 = app.v_thickness_2(app.exp_counter);
app.h_thick1 = app.h_thickness_1(app.exp_counter);
app.h_thick2 = app.h_thickness_2(app.exp_counter);
v_or_h = app.v_or_h_array(app.exp_counter);
%Vertical line
if v_or_h == 0
app.region1 = patch(app.UIAxes, ...
[v_thick1 v_thick2 v_thick2 v_thick1], ...
[-10 -10 10 10],'r', ...
'FaceAlpha',1,...
'LineWidth',0.01, ...
'LineStyle','-','tag','region1');
%Horizontal line
elseif v_or_h == 1
app.region1 = patch(app.UIAxes,[-10 10 10 -10], ...
[app.h_thick1 app.h_thick1 app.h_thick2 app.h_thick2], ...
'r','FaceAlpha',1,...
'LineWidth',0.01, ...
'LineStyle','-','tag','region1');
end
% Define pointer behavior for patch
pm.enterFcn = @(~,~) cursorPositionFeedback(app, app.region1, 'in');
pm.exitFcn = @(~,~) cursorPositionFeedback(app, app.region1, 'out');
pm.traverseFcn = [];
iptSetPointerBehavior(app.region1, pm)
% Enable pointer manager for app
iptPointerManager(app.UIFigure,'enable');
% Create the Arduino serial object
app.arduinoObj = serialport("COM6", 9600);
configureTerminator(app.arduinoObj,"CR/LF");
%flush(app.arduinoObj);
%
for i=1:8
app.message = readline(app.arduinoObj);
disp(app.message)
end
function cursorPositionFeedback(app, hobj, inout)
% When inout is 'in', change hobj facecolor to green and update textbox.
% When inout is 'out' change hobj facecolor to red, and clear textbox.
% Check tag property of hobj to identify the object.
switch lower(inout)
case 'in'
facecolor = 'g';
txt = 'Motor(s) vibrating';
pointer = 'fleur';
writeline(app.arduinoObj, "4&MOTOR_1_2&0!");
% message = readline(app.arduinoObj);
% disp(message)
case 'out'
facecolor = 'r';
txt = 'No';
pointer = 'crosshair';
writeline(app.arduinoObj, "0&NO_MOTOR&0!");
% message = readline(app.arduinoObj);
% disp(message)
end
hobj.FaceColor = facecolor;
app.TextAreaEditField.Value = txt;
set(app.UIFigure, 'Pointer', pointer)
end
@Franck paulin Ludovig pehn Mayo - you would need to look at the values being assigned to
v_thick1 = app.v_thickness_1(app.exp_counter);
v_thick2 = app.v_thickness_2(app.exp_counter);
h_thick1 = app.h_thickness_1(app.exp_counter);
h_thick2 = app.h_thickness_2(app.exp_counter);
Are they all non-empty? Are they all scalars? Given the other input to patch being
[-10 -10 10 10],
you must ensure that the other array which is composed of the v_ and h_ variables are defined appropriately so that you create a 1x4 array.
@Franck paulin Ludovig pehn Mayo - even with your data and simplified version of your code, I cannot get that same error to appear. Does it occur always or after some number of times of pressing the NEXT button?
I think that you will need to use the debugger to step through the code to understand what is happening (since I don't have your GUI nor a clear set of steps on what is happening).
Hello @Geoff Hayes ,
I have used the debug mode and i found the issue.But now, another issue came up but matlab is not showing any error.The issue was, i needed to define h_tchick and v_thick under properties.I have edited the previous code.
The issue is this:
my excel files have 8 rows so 8 iterations and the Gui is just taking into consideration the first two rows when i click on the next button.
Furthermore, when the mouse is on the band(line),the red band is supposed to go green and the text edit is supposed to say: motors vibratings ; and no motor when it is out of the band
When i run the gui, everything is fine.The band goes green and the text edit is saying motors vibrating but as soon as i click on the next button , the first 2 first rows are just taking into considerations and the band remains red....
Attached is the gui (the general view).
Thise are all the properties defined
properties (Access = public)
arduinoObj % Description
message
end
properties (Access = public)
T % Description
end
properties (Access = public)
region1
%
v_thick1 % Description
v_thick2 % Description
h_thick1 % Description
h_thick2 % Description
v_thickness_1
v_thickness_2
h_thickness_1
h_thickness_2
v_or_h_array
amplitude_array
exp_counter
end
properties (Access = public)
amplitude % Description
end
methods (Access = private)
function mycallback(app,src,event)
display(event.SelectedOption);
end
end
@Franck paulin Ludovig pehn Mayo - unfortunately, I don't have the Image Processing Toolbox or an Arduino so cannot run the GUI
iptPointerManager(app.UIFigure,'enable');
% Create the Arduino serial object
app.arduinoObj = serialport("COM6", 9600);
From yout comment,
my excel files have 8 rows so 8 iterations and the Gui is just taking into consideration the first two rows when i click on the next button.
what should happen when the user clicks on the next button? What rows should be used on subsequent calls to "next"? Here is the code for that callback
% Button pushed function: NEXTButton_2
function NEXTButton_2Pushed(app, event)
uiconfirm(app.UIFigure,'Are You sure?','Confirm Close',...
'CloseFcn',@(src,event)mycallback(app,src,event));
app.exp_counter = app.exp_counter + 1;
app.v_or_h = app.v_or_h_array(app.exp_counter);
if ishandle(app.region1)
delete(app.region1);
end
%Vertical line
if app.v_or_h == 0
app.region1 = patch(app.UIAxes,...
[app.v_thick1 app.v_thick2 app.v_thick2 app.v_thick1],...
[-10 -10 10 10],'r',...
'FaceAlpha',1,...
'LineWidth',0.01,...
'LineStyle','-','tag','region1');
%Horizontal line
elseif app.v_or_h == 1
app.region1 = patch(app.UIAxes,[-10 10 10 -10],...
[app.h_thick1 app.h_thick1 app.h_thick2 app.h_thick2],...
'r','FaceAlpha',1,...
'LineWidth',0.01,...
'LineStyle','-','tag','region1');
end
end
Is the issue with the app.h_thick1, app.v_thick1, etc.? If so, then why not, once you have incremented app.exp_counter then do
app.v_thick1 = app.v_thickness_1(app.exp_counter);
app.v_thick2 = app.v_thickness_2(app.exp_counter);
app.h_thick1 = app.h_thickness_1(app.exp_counter);
app.h_thick2 = app.h_thickness_2(app.exp_counter);
which should give you the next set of data. So the callback would look like
% Button pushed function: NEXTButton_2
function NEXTButton_2Pushed(app, event)
uiconfirm(app.UIFigure,'Are You sure?','Confirm Close',...
'CloseFcn',@(src,event)mycallback(app,src,event));
app.exp_counter = app.exp_counter + 1;
app.v_or_h = app.v_or_h_array(app.exp_counter);
app.v_thick1 = app.v_thickness_1(app.exp_counter);
app.v_thick2 = app.v_thickness_2(app.exp_counter);
app.h_thick1 = app.h_thickness_1(app.exp_counter);
app.h_thick2 = app.h_thickness_2(app.exp_counter);
if ishandle(app.region1)
delete(app.region1);
end
%Vertical line
if app.v_or_h == 0
app.region1 = patch(app.UIAxes,...
[app.v_thick1 app.v_thick2 app.v_thick2 app.v_thick1],...
[-10 -10 10 10],'r',...
'FaceAlpha',1,...
'LineWidth',0.01,...
'LineStyle','-','tag','region1');
%Horizontal line
elseif app.v_or_h == 1
app.region1 = patch(app.UIAxes,[-10 10 10 -10],...
[app.h_thick1 app.h_thick1 app.h_thick2 app.h_thick2],...
'r','FaceAlpha',1,...
'LineWidth',0.01,...
'LineStyle','-','tag','region1');
end
end
Thank you .You helped me a lot. I said what you adviced me and i have to copy some other lines for the Gui to be perfect.
Sorry, i am facing another challenge but this one seems not that bulky. (BUT , i will accept your answer)
As the example of the Gui i have attached two days earlier, you can see there are two push buttons "YES, I FEEL IT" and" No I DONT". I would like that when those two buttons are pushed ,i want the information to be saved. I did a code about them and they are working. The only problem is that , they erased the previous one.
To be more explicit, if the cursor goes on the band/line, the subject will either feel it or not .So if he feels it for instance , he should click on the "YES, I FEEL IT'', otherwise the other button ''NO, I DONT''. Then he will click on the NEXT BUTTON we have been working earlier and consequently.
The issue is that it is just the last answer that is saved. I dont know if it is possible to save everything in one file.
This is the code;It is both the same ...I just change the ''YES'' with the ''NO''
uiconfirm(app.UIFigure,'Are You sure?','Confirm Close',...
'CloseFcn',@(src,event)mycallback(app,src,event));
clear
clc
fileID = fopen('exp.txt2','w');
YES = "I FEEL IT";
fprintf(fileID,"%s",YES);
fclose(fileID);
@Franck paulin Ludovig pehn Mayo - are you just writing a string to the text file? if so, then just append to the file rather than write and discard the existing contents. Please see file type access and so you would change your code from
fileID = fopen('exp.txt2','w');
to
fileID = fopen('exp.txt2','a');
Note that you should add a check in your code to make sure the fileID is valid before trying to write data to the file (i.e. fileID > 0).
Also, you may want to write to a new line each time (or not?) so add the \n to your fprintf
fprintf(fileID,"%s\n",YES);
@Geoff Hayes Thank you very much. It has been solved .I deeply appreciate that. Blessings.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Tags

Community Treasure Hunt

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

Start Hunting!

Translated by