I have a Matlab GUI which takes input in p array from different functions by different methods, my question is how I can terminates uiwait when the input of p array is taken, such that when any function of input is terminated successfully. I'm trying to put uiresume but it doesn't work on my side.
My code (Main Function):
function varargout = GUI(varargin)
if nargin == 0
fig = openfig(mfilename,'reuse');
handles = guihandles(fig);
guidata(fig, handles);
uiwait (fig);
if nargout > 0
varargout{1} = fig;
end
elseif ischar(varargin{1})
try
if (nargout)
[varargout{1:nargout}] = feval(varargin{:});
else
feval(varargin{:});
end
catch
end
end
I don't really get what exactly your code is supposed to do.
In any case:
uiresume has to be placed somewhere in a callback of the gui you're opening, since you're above code stops running in the uiwaitline.
So, you might have an "Ok"-Button on your GUI with a callback à la:
function ok_button_callback(object, evt, handles)
fig = ancestor(object, 'figure');
uiresume(fig);
end
Related
I know several variants of this issue have been discussed elsewhere, but I am still unable to solve the problem. Please help.
I have created a function as part of a larger gui, but I am unable to store three data variables (AveX, AveY, AveZ) for later use by guidata(hObject, handles).
What am I doing wrong?
Here is the function:
%call all checkbox values
for i = 1:30
checkboxes=get(handles.(sprintf('checkboxAv%d',i)),'value')
Checkboxes(i,1)=checkboxes(1,1);
end
plotdata=handles.plotdata;
[row,col] = find(Checkboxes==1)
num=length(plotdata{1,1}(:,1));
DataY = zeros(num,length(row));%zero matrix
%Average y data
for k=1:length(row)
DataY(:,k)=plotdata{row(k,1),col(k,1)}(:,4);
end
[m,n] = size(DataY)
if (n==1)
AveY=DataY'
elseif (n>1)
AveY=mean(DataY');
end
AveY=AveY';
%Average X data
for kk=1:length(row)
DataX(:,kk)=plotdata{row(kk,1),col(kk,1)}(:,1);
end
test=DataX(:,1);
comp=any(bsxfun(#minus,DataX,test),1)
S = sum(comp)
if (S > 0)
h=msgbox(['Note! Wavelength index for the selected samples are not identical.'])
end
[c,r] = size(DataY)
if (r==1)
AveX=DataX'
elseif (r>1)
AveX=mean(DataX');
end
AveX=AveX';
%Average Z data
for kkk=1:length(row)
DataZ(:,kkk)=plotdata{row(kkk,1),col(kkk,1)}(:,5);
end
[m,n] = size(DataZ)
if (n==1)
AveZ=DataZ'
elseif (n>1)
AveZ=mean(DataZ');
end
AveZ=AveZ';
handles.Aveheader=Aveheader
handles.AveX=AveX;
handles.AveY=AveY;
handles.AveZ=AveZ;
guidata(hObject, handles);
And here is the error message:
Undefined function or variable 'hObject'.
Error in CDanalyzer>AveragePlotFcn (line 5276)
guidata(hObject, handles);
Error in CDanalyzer>checkboxAv1_Callback (line 5076)
AveragePlotFcn(handles)
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in CDanalyzer (line 17)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>#(hObject,eventdata)CDanalyzer('checkboxAv1_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
"guidata(object_handle,data) stores the variable data with the object specified by object_handle" you need to specify the object_handle. Currently hObject is undefined in this local function.
Use gcbo instead, which "returns the handle of the graphics object whose callback is executing":
guidata(hObject, handles);
becomes
guidata(gcbo, handles);
Alternatively, add hObject as an input to the function AveragePlotFcn. So:
function AveragePlotFcn(hObject,~)
...
end
I am working on a GUI in MATLAB; I used the GUIDE in the command window.
I have several pushbuttons.
Now the problem, I have a function, in a pusbhbutton4 and when I click on it I want to plot the result in three specific axes (10 - 12).
But does not work.
The code:
function pointsQRS = MyCustomPushButtonFunctionQRS10(VxQRS, VyQRS, VzQRS)
VxQRS=[[0:length(VxQRS)-1]' VxQRS];
axes(handles.axes10);
plot(VxQRS(:,2));
grid on
Vx_QRS=ginput;
x_pointsQRS=VxQRS(Vx_QRS(1,1)<=VxQRS(:,1) & Vx_QRS(2,1)>=VxQRS(:,1),:);
m=1;
VyQRS=[[0:length(VyQRS)-1]' VyQRS];
axes(handles.axes11);
plot(VyQRS(:,2));
grid on
Vy_QRS=ginput;
y_pointsQRS=VyQRS(Vy_QRS(1,1)<=VyQRS(:,1) & Vy_QRS(2,1)>=VyQRS(:,1),:);
if size(y_pointsQRS,1)<m
m=2;
end
VzQRS=[[0:length(VzQRS)-1]' VzQRS];
axes(handles.axes12);
plot(VzQRS(:,2));
grid on
Vz_QRS=ginput;
z_pointsQRS=VzQRS(Vz_QRS(1,1)<=VzQRS(:,1) & Vz_QRS(2,1)>=VzQRS(:,1),:);
if size(z_pointsQRS,1)<m
m=3;
end
switch m
case 1
x_pointQRS=x_pointsQRS;
y_pointQRS=y_pointsQRS(x_pointsQRS(1,1)<=y_pointsQRS(:,1) & x_pointsQRS(end,1)>=y_pointsQRS(:,1),:);
z_pointQRS=z_pointsQRS(x_pointsQRS(1,1)<=z_pointsQRS(:,1) & x_pointsQRS(end,1)>=z_pointsQRS(:,1),:);
case 2
y_pointQRS=y_pointsQRS;
x_pointQRS=x_pointsQRS(y_pointsQRS(1,1)<=x_pointsQRS(:,1) & y_pointsQRS(end,1)>=x_pointsQRS(:,1),:);
z_pointQRS=x_pointsQRS(y_pointsQRS(1,1)<=z_pointsQRS(:,1) & y_pointsQRS(end,1)>=z_pointsQRS(:,1),:);
case 3
z_pointQRS=z_pointsQRS;
x_pointQRS=x_pointsQRS(z_pointsQRS(1,1)<=x_pointsQRS(:,1) & z_pointsQRS(end,1)>=x_pointsQRS(:,1),:);
y_pointQRS=y_pointsQRS(z_pointsQRS(1,1)<=y_pointsQRS(:,1) & z_pointsQRS(end,1)>=y_pointsQRS(:,1),:);
end
size_min=min([size(x_pointQRS,1) size(y_pointQRS,1) size(z_pointQRS,1)])
pointsQRS([1:size_min],:)=[x_pointQRS([1:size_min],2) y_pointQRS([1:size_min],2) z_pointQRS([1:size_min],2)];
if size_min==0
error('Wrong.');
end
end
The pushbutton code:
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, Data)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
pointsQRS = MyCustomPushButtonFunctionQRS10(Data.fileData(:,1), Data.fileData(:,2), Data.fileData(:,3))
save 'pointsQRS.mat' -mat pointsQRS
Error I'm still getting:
Undefined variable "handles" or class "handles.axes10".
Error in MyCustomPushButtonFunctionQRS10 (line 3)
axes(handles.axes10);
Error in VKG_Zobrazovac>pushbutton4_Callback (line 156)
pointsQRS = MyCustomPushButtonFunctionQRS10(Data.fileData(:,1), Data.fileData(:,2), Data.fileData(:,3))
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in VKG_Zobrazovac (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in #(hObject,eventdata)VKG_Zobrazovac('pushbutton4_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback
Could you please give me any hint how to make it work properly?
You are not passing the handles struct to MyCustomPushButtonFunctionQRS10 (or as you call it, Data) so it has no way to access the axes handles stored in handles. You should pass handles as an input argument.
pointsQRS = MyCustomPushButtonFunctionQRS10(Data.fileData(:,1), ...
Data.fileData(:,2), ...
Data.fileData(:,3), ...
Data)
And then your callback would accept a fourth input
function pointsQRS = MyCustomPushButtonFunctionQRS10(VxQRS, VyQRS, VzQRS, handles)
Additionally, I would recommend using the 'Parent' property of plot to specify the parent axes rather than using axes.
plot(VxQRS(:,2), 'Parent', handles.axes10);
grid(handles.axes10, 'on')
Vx_QRS = ginput(handles.axes10);
Suppose vec_A, vec_B, vec_c are some matrices with random data. I want to write data to text file for every 5 min, My code as follows:
function samplegui_OpeningFcn(hObject, ~, handles, varargin)
handles.timer = timer(...
'ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 300, ... % Initial period.
'TimerFcn', {#open,hObject}); % Specify callback
handles.output = hObject;
handles.vec_A=[];
handles.vec_B=[];
handles.vec_C=[];
guidata(hObject, handles);
function open_Callback(hObject, eventdata, handles) % push button to receive serial data.
cnt=0;
while 1
% Getting data from Serial Port
get_lines=fgets(handles.se) % getting data from serial port
if~isempty(get_lines)
cnt=cnt+1;
if strfind(get_lines,'T') %Parsing data
handles.vec_A=[handles.vec_A;[timet newword]];
plot(handles.vec_A(:,1),handles.vec_A(:,2:end),'r'); % plotting
% Same follows for parsing and plot vec_B and Vec_C
drawnow(); % to update the Plots
end
end
Pause(.05);
start(handles.timer); % saving the data
dlmwrite('My_sample1.txt',handles.vec_A);
dlmwrite('My_sample2.txt',handles.vec_B);
dlmwrite('My_sample3.txt',handles.vec_C);
stop(handles.timer);
end
guidata(hObject, handles);
While running my code, following error occurs:
Error while evaluating TimerFcn for timer 'timer-6'
Too many input arguments.
How to execute timer in this case to write data successfully for every five minutes or suggest any other way to do it.
You have defined your TimerFcn to be {#open, hObject} but you don't have a function named open. Instead, it is trying to call the built-in open with three input arguments (the timer object, an event object, and hObject) and this is producing the error because open only accepts one input argument.
That being said, it's not clear at all how the code that you have provided will accomplish anything close to what you want. Something like this may work better.
function samplegui_OpeningFcn(hObject, ~, handles, varargin)
handles.timer = timer(...
'ExecutionMode', 'fixedRate', ... % Run timer repeatedly
'Period', 300, ... % Initial period.
'TimerFcn', #(s,e)write_data()); % Specify callback
handles.output = hObject;
handles.vec_A=[];
handles.vec_B=[];
handles.vec_C=[];
guidata(hObject, handles);
start(handles.timer);
%// Now update your data in a loop
cnt = 0;
while true
%// Getting data from Serial Port
get_lines = fgets(handles.se)
if ~isempty(LINES)
cnt = cnt + 1;
if strfind(LINES, 'T')
handles.vec_A = [handles.vec_A; [timet newword]];
plot(handles.vec_A(:,1), handles.vec_A(:,2:end),'r');
drawnow
end
end
end
function write_data()
%// Write it to file
dlmwrite('My_sample1.txt',handles.vec_A);
dlmwrite('My_sample2.txt',handles.vec_B);
dlmwrite('My_sample3.txt',handles.vec_C);
end
end
I have a matlab code running in a loop. The code is pretty heavy and time-consuming. Instead of using Ctrl-C, I am looking for a way to abort the function with GUI callback in runtime. I have my code designed as follows
function test
figure;
uicontrol('pos',[20 20 40 20],'string','abort','fontsize',12, 'callback', 'error(''p'');');
k=0;
while(k<10000)
m=1:10000;
x = rand(size(m));
for t=1:10000
x=x+sin(2*pi*m*0.02 + mod(t, 5)*pi);
end
% other code will be run here
plot(m, x);
drawnow;
k=k+1
end
end
Above code just as an example. I know it could be optimized but I don't concern about that now. I just want to know why above code doesn't work. The callback in which the 'error' function issued will not abort the code. How to make it work? Thanks.
The error callback is not called within the loop. Hence, the error callback and the loop are independent processes.
You could design your function this way:
function test
figure;
AbortButton = uicontrol('Style','togglebutton','pos',[20 20 40 20],'string','abort','fontsize',12);%, 'callback', 'error(''p'');');
k=0;
figure;
while(k<10000)
val = get(AbortButton,'val');
if (val == 0)
m=1:10000;
x = rand(size(m));
for t=1:10000
x=x+sin(2*pi*m*0.02 + mod(t, 5)*pi);
end
% other code will be run here
plot(m, x);
drawnow;
k=k+1;
elseif (val == 1)
break;
end
end
end
This is a rudimentary way, but might help.
I have a problem in my GUI. In my opening function I defined an img_new variable to be an image I have stored.
My GUI has two axes, one displays the original image and the other one the filtered one. I have 4 filters in a panel with the 4 radiobuttons. And in the end of each one's code there's the img_new = the image created through the radiobutton filter.
Here's some code:
% --- Executes when selected object is changed in uipanel3.
function uipanel3_SelectionChangeFcn(hObject, eventdata, handles)
handles.count = handles.count + 1;
% Change filter orientation depending on which radiobutton is chosen
switch get(eventdata.NewValue,'Tag')
case 'hte'
h_te = zeros(handles.rows, handles.colums);
# code of the filter...
axes(handles.axes2);
imshow(h_te);
handles.img_new = h_te;
case 'hc'
h_c = zeros(handles.rows, handles.colums);
# code of the filter...
axes(handles.axes2);
imshow(h_c);
handles.img_new = h_c;
case 'vlr'
v_lr = zeros(handles.rows, handles.colums);
# code of the filter...
axes(handles.axes2);
imshow(v_lr);
handles.img_new = v_lr;
case 'vc'
v_c = zeros(handles.rows, handles.colums);
# code of the filter...
axes(handles.axes2);
imshow(v_c);
handles.img_new = v_c;
end
guidata(hObject, handles)
and here's the imwrite function:
% --------------------------------------------------------------------
function save_img_ClickedCallback(hObject, ~, handles)
% writing the new image
imwrite(handles.img_new, strcat('filtered_image_', num2str(handles.count), '.png'));
guidata(hObject, handles)
Here's the function to get the image to axes1 the original) and filter it to axes2 (filtered)
% --- Executes on button press in img2.
function img2_Callback(hObject, ~, handles)
% Read image 2
img = imread('./coimbra_estadio.jpg');
handles.img_d = im2double(img);
% image size
size_img = size(handles.img_d);
handles.colums = size_img(2);
handles.rows = size_img(1);
if rem(handles.rows,2) == 0
handles.row_0 = ((handles.rows/2)+1);
else
handles.row_0 = ((handles.rows/2)+0.5);
end
if rem(handles.colums,2) == 0
handles.colum_0 = ((handles.colums/2)+1);
else
handles.colum_0 = ((handles.colums/2)+0.5);
end
axes(handles.axes1);
imshow(img);
% Generate eventdata to call the radiobuttons function
eventdata_new.EventName = 'SelectionChanged';
eventdata_new.OldValue = get(handles.uipanel3,'SelectedObject');
eventdata_new.NewValue = get(handles.uipanel3,'SelectedObject');
uipanel3_SelectionChangeFcn(handles.uipanel3, eventdata_new, handles);
guidata(hObject, handles)
As you can see, in the end I call the panel function so when the image is loaded it is automatically filtered and the axes2 image changes.
The problem is when I call the save function it saves the old img_new.
If I change the radiobutton the img_new is refreshed, but if it is not changed it is not refreshed. It should be as loading an image automatically calls for the panel of radiobuttons function.
The problem is that guidata(hObject,handles); at the end of img2_Callback saves old handles object as a final gui state, updates made in uipanel3_SelectionChangeFcn are lost. You need to eitehr manually update handles after calling uipannel3_SelectionChangeFcn by putting handles = guidata(hObject,handles);
or handles=guidata(hObject);
(forgot which call to guidata updates handles, please see help for that), or simply remove the line guidata(hObject,handles); at the end of img2_callback (less safe if code is going to change later, updating handles after uipannel3_SelectionChangeFcn is safer approach...