GUI scrollbar error - matlab

I'm trying to create a scrolling list within a GUI using nested panels. However, whenever I try to move the scrollbar in the GUI, I receive this error:
??? Error using ==> PyroGUI>slider Too many input arguments.
???
Error while evaluating uicontrol Callback
Here is my code:
screensize=get(0,'ScreenSize');
handles.fig=figure('Position',[100 100 screensize(3)-150 screensize(4)-150]);
handles.hpanel=uipanel(handles.fig,'Position',[0.005 0.01 0.99 0.99],'Title','Panel');
handles.hsp = uipanel('Parent',handles.hpanel,'Title','Subpanel','FontSize',12,...
'Position',[.025 .05 .3 .935]);
handles.hpop = uicontrol('Style', 'slider',...
'Position', [20 30 20 700],...
'Min',1,'Max',700,'Value',700,...
'callback', {#slider,handles.hsp});
handles.pos=get(handles.hpanel,'Position');
function slider()
slidervalue=get(handles.hpop,'Value');
set(handles.hpanel,'Position',[handles.pos(1) handles.pos(2)-slidervalue+1 handles.pos(3) handles.pos(4)]);
end
Any ideas as to what could be causing this?

If you provide a callback function for uicontrol, it always needs two input arguments like this (even if you don't need them)
function slider(hobj, evnt)
slidervalue=get(handles.hpop,'Value');
set(handles.hpanel,'Position',[handles.pos(1) handles.pos(2)-slidervalue+1 handles.pos(3) handles.pos(4)]);
end
Edit: See here http://www.mathworks.de/de/help/matlab/creating_guis/examples-programming-gui-components.html

Related

How to reset the default values in a graphical user interface

I'm creating a graphic interface (manually) and I would like to have a reset button which reset the default values.
I already code this
H.but(3) = uicontrol('Units','normalized', ...
'BackgroundColor',[1 0.7 1], ...
'Callback','MyFunction(''Reset'');', ...
'FontSize',12, ...
'Position',[0.04 0.54 0.1 0.05 ], ...
'String','Reset');
case 'Reset'
clear all % Is not working and I think that isn't that I expect
set(findobj(H.fig,'style','edit', '-or','style','text'),'string','') % H is a global variable. This trial don't give the default value, it just clear certain boxes
I usually prefer to create a specific reset_gui function for my GUIs that resets all the relevant control properties (like checkbox states, strings in editable text boxes, etc.) to appropriate default values, as well as setting all relevant variable values to their defaults, clearing plots, etc..
If you'd prefer a generic option for resetting all UI control properties to their initial state, here's an example of one possible solution:
function example_reset_gui
% Initialize GUI:
hFigure = figure();
uicontrol('Style', 'edit', 'Position', [20 100 100 25]);
uicontrol('Style', 'edit', 'Position', [20 65 100 25]);
uicontrol('Style', 'push', 'Position', [20 20 60 30], ...
'String', 'Reset', 'Callback', #reset_fcn);
drawnow
% Collect default states:
[defaultState{1:3}] = get_default_state(hFigure);
% Nested reset function:
function reset_fcn(~, ~)
set(defaultState{:});
end
end
% Local function:
function [hArray, propArray, valueArray] = get_default_state(hFigure)
hArray = findall(hFigure, 'Type', 'uicontrol');
propArray = fieldnames(set(hArray(1)));
valueArray = get(hArray, propArray);
end
This creates a figure with 2 editable text boxes and a reset button. You can type whatever you want into the text boxes, and when you push the reset button it will clear them (i.e. set them to the default empty string they first contained).
The local function get_default_state will find all the uicontrol objects in the figure, then get all of their set-able properties (i.e. all properties that are not read-only), then get all the initial values for those properties. The three outputs are stored in the 1-by-3 cell array defaultState, which is accessible by the nested function reset_fcn. When the reset button is pressed, all of the set-able UI control properties are set to the values they had when first created.
It should be noted that any changes made to the Position property (such as due to resizing of the figure) could be undone by this approach. Using 'normalized' units would avoid this.
If you truly want to start your GUI over from scratch the easiest way would be to just close it open it again. You can do that from your button's callback. Which I pointed at a new function restartGUI. That could be a subfunction of your main gui or its own m-file, your choice.
Your question is pretty light on details so I can't help with some of the specifics but this should give you the general idea.
IF closing and opening isn't what your want then in the restartGUI function you would have to just manually reset the state of each of your uicontrols, etc. (whatever else is in your GUI that we can't see).
H.but(3) = uicontrol('Units','normalized', ...
'BackgroundColor',[1 0.7 1], ...
'Callback',#restartGUI, ...
'FontSize',12, ...
'Position',[0.04 0.54 0.1 0.05 ], ...
'String','Reset');
% <<<< THE rest of your code >>>
function restartGUI(hObject,varargin)
global H
close(H.fig) %Assuming H.fig the main GUI window.
%Call the GUI again which will restart it.
yourGUIFunction
Edit: added the use of the global H to close.

Make a panel with values visible when I press a radiobutton

I have a uibuttongroup with radio buttons defined in it. I have uipanels defined with their corresponding properties. What I want to do is to be able to click one radio button and have one uipanel appear, and then click my other radio button to have the other uipanel appear. Here are snippets of my code:
operation_type_1 = uibuttongroup(S.Test, 'Title', 'Operation Type', 'position', [0 0.3 panel_w/2 0.15]);
uicontrol('Parent',operation_type_1, 'Style', 'radiobutton',...
'String', 'invisible',...
'position', [0 0 0 0], 'Tag', 'invisibutton');
uicontrol('Parent',operation_type_1,'Style','radiobutton',...
'String', 'Time Operation',...
'Position', 100*[0.1 flooring(3.5, 'tp') 1.2 0.15], 'Tag', 'timeop1');
uicontrol('Parent',operation_type_1,'Style','radiobutton',...
'String', 'Volume Operation',...
'Position', 100*[0.1 flooring(2.5, 'tp') 1.2 0.15], 'Tag', 'volumeop1');
This defines my button group and the two radio buttons.
Then I have code which creates a volume panel:
As well as a Time Panel:
These are in the same position. What I want is to be able to click on the "Time Operation" radio button and have the time panel be visible, and when I click on the "Volume Operation" radio button, the volume panel is visible.
I've tried doing switch case statements. I don't get errors, but I don't get results either. For example, my case statements for the time and volume panels are:
switch str
case 'timeop1'
if U.Value; S.result_panel_time1.Visible = 'On';
else S.result_panel_time1.Visible = 'Off';
end
case 'volumeop1'
if U.Value; S.result_panel_volume1.Visible = 'On';
else S.result_panel_volume1.Visible = 'Off';
end
How do I get this to work? I'm not using GUIDE, just coding a MATLAB GUI.
UPDATE
I've tried implementing the callback suggested below, but I get a "Function definition is misplaced or improperly nested." error. I use the following function:
function button_callback(U, varargin{2})
switch get(get(operation_type_1, 'SelectedObject'), 'Tag')
case 'timeop1'
if U.Value; S.result_panel_time1.Visible = 'On';
else S.result_panel_time1.Visible = 'Off';
end
case 'volumeop1'
if U.Value; S.result_panel_volume1.Visible = 'On';
else S.result_panel_volume1.Visible = 'Off';
end
end
end
And I've added the callbacks "...'callback', {#pb_call, S}" to my timeop1 and volumeop1. (Because all of the other function I have are in a .m file called pb_call.m). The function appears to be nested fine but the error points at the exact one.
It seems to me you did not define callback for your RadioButton. For example, set callback for volumeop1:
uicontrol('Parent',operation_type_1,'Style','radiobutton',...
'String', 'Volume Operation',...
'Position', 100*[0.1 0.3 1.2 0.15], 'Tag', 'volumeop1', ...
'Callback', #switchPanel);
Then in function switchPanel, you will set corresponding panel visible, while set others invisible.
This is trying to answer your questions, but it seems to me what you want is uitab.
My partner ended up fixing it:
The callback was {callback, S} and S, U, and str were:
S = varargin{3}; %main figure handle
U = varargin{1}; %current uicontrol
str = char(U.String);
The problem occurred in the radiobutton creation, since the result panels were being created after the radiobuttons could be triggered, thus nothing was made invisible/visible and an error would occur.
However, it would be highly convenient if callbacks could affect all GUI parts, not just previously defined ones. I've tried using guidata in the past, but I had to use other, less straighforward methods to accomplish my goals. I'll try using working samples and building upon those in the future, but currently I am working on another part of the project and will get back to that later.
But using either guidata/setappdata or something related would work here as well as my own solution, which is making sure that the objects you are trying to change are already defined before the button triggering the callback.
(He also posted this answer to where I asked this same question in MATLAB Answers.)

Cannot call callback of the pushbutton of the uicontrol in matlab

I am trying to create a button in GUI matlab and call a function when it is pressed. This code it is not working. I have also tried to use these values in the last argument of uicontrol:
fnHi, 'fnHi', 'fnHi();'
The code is:
function [] = testui()
function fnHi()
fprintf('hi');
end
fnHiHandler = #fnHi;
fnHiHandler(); fnHi();
figure();
uicontrol('Style', 'pushbutton', 'string', 'Hi', 'callback', fnHiHandler);
end
The output is:
testui()
hihiUndefined function or variable 'fnHiHandler'.
Error while evaluating uicontrol Callback
So the function works since it is called twice but when I press the button it crashes.
I dont want to use more than one file. Thank you.
Ok, I found the answer. The problem is that fnHi should receive two arguments, otherwise it will crash saying that are too many input arguments. So this code works:
function [] = testui()
function fnHi(source,eventdata)
fprintf('hi');
end
fnHiHandler = #fnHi;
fnHiHandler(); fnHi();
figure();
uicontrol('Style', 'pushbutton', 'string', 'Hi', 'callback', fnHiHandler);
end

How to view a more than 1 lines of sentences to uipanel in matlab?

I wanna view the result of the "Detection" function.
In the "Detection" function there is "messeges" variable.
From the function, i want that all the sentences in messeges variable can be preview in my GUI esspecially in UIPANEL.
How to do it. I have made a Panel design in matlab with tag=uipanel1.
[messeges]=Detection(handles.citra1); %it's to call the Detection
function.
here is my UIPANEL CODE..
hp1=uipanel('Position', [100 100 700 500],...
'Title','UI Panel 1');
set(hp1, [messeges]);
but it cannot display the sentences from the messeges variable into the panel1 that i had made before..
There are errors messeges like this
??? Error using ==> set
There is no 'jumlah pasang pixel yang pada objek 13
adalah 1000' property in the 'uipanel' class.
Error in ==> deteksi2citra>pushbutton3_Callback at 124
set(hp1, [messeges]);
Error in ==> gui_mainfcn at 96
feval(varargin{:});
Error in ==> deteksi2citra at 42
gui_mainfcn(gui_State, varargin{:});
Error in ==>
#(hObject,eventdata)deteksi2citra('pushbutton3_Callback',
hObject,eventdata,guidata(hObject))
??? Error while evaluating uicontrol Callback
I have find the rellated topic but i cannot find the solution.
Please help me..
There are three major problems with your code.
You always have to set a property of an object to something in Matlab.
set(Object_Handle,'PropertyName1',PropertyValue1,...
'PropertyName2',PropertyValue2...)
Thus you might be able to write this set(hp1, 'String', messages); but never set(hp1, [messages]);
uipanel is just a container object, which means that it could contain other GUI objects. You could put a text or edit (See uicontrol) containing your string in the uipanel. But the uipanel itself does not have a 'String' property.
The position vector of uipanel is normalized by default. So all the position values must be between 0 and 1. See position vector here for more info.
Example of putting multi-line text in uipanel:
(Note that this code is a standalone or self consistent code (unlike GUIDE), thus you can just copy and paste this code and run it in matlab command window.)
str = sprintf('Your \n Multiline \n String ...');
hp1 = uipanel('Title','UI Panel 1',...
'Position', [.25 .1 .67 .67]);
uicontrol(...
'Parent', hp1,...
'Style','text',...
'Units', 'Normalized', 'Position', [0 0 1 1],...
'String', str);

using drawnow: Interrupt while evaluating uicontrol Callback

I have a problem with a while loop inside a switch-case statement, used together with callback functions and "drawnow". In my code, while the cases of the switch-case are determined by pushbuttons in uicontrol, the case statements involves further callback functions to track mouse movements using 'windowbuttondown/up/motionfcn's. Because I draw multiple plots inside the while loop in the case statement, however, I use 'drawnow', which gives me the following error when I run the programme:
Error on line 160 ==> drawnow
??? Interrupt while evaluating uicontrol Callback
The piece of code inside the case statement gives no error when I run independently but somehow creates problem when is integrated with the rest of the code, which I attach below. Any help would be so much appreciated. Many thanks!
function programme(selection)
if nargin == 0
selection=0
end
switch selection
case 0 %start GUI and uicontrols to set up the cases i.e programme(1), programme(2) etc
uicontrol('style','pushbutton',...
'string','First', ...
'position',[50 700 50 20], ...
'callback','programme(1);');
uicontrol('style','pushbutton',...
'string','Second', ...
'position',[150 700 50 20], ...
'callback','programme(2);');
case 1
%mouse track:
set(gcf,'windowbuttondownfcn','mousedown=1;');
set(gcf,'windowbuttonupfcn','mouseup=1;');
set(gcf,'windowbuttonmotionfcn','mousemotion=1;');
%to terminate the while loop, set up stopit=1 on one of uicontrol buttons:
uicontrol('style','pushbutton',...
'string','First', ...
'position',[50 700 50 20], ...
'callback','stopit=1;');
stopit=0;
while (stopit==0)
if mousedown==1
statements
if mouseup ==1
statements (plots)
mouseup=0;
mousedown=0;
mousedown=0;
end
end
drawnow
end
case 2
statements
otherwise
statements
end
Look in the help: drawnow
It interrupts callbacks. And you call your function in a callback. Maybe you can replace it with a pause(0.01).
Though I would strongly advise you to get rid of the loop and use callbacks instead.