Thank you for your answer. I should have been more clear. I need a text object for every line. Here's how far I got:
function calc_slope(handle,event)
on = get(handle,'State');
if strcmpi(on,'on') || strcmpi(on,'off'),
xy = imline;
addNewPositionCallback(xy,#(pos) disp_slope(pos));
end
function disp_slope(pos)
delete(findobj(gca,'Type','text'));
text((pos(1)+pos(2))/2,(pos(3)+pos(4))/2,['\DeltaY/\DeltaX = ',num2str((pos(4)-pos(3))/(pos(2)-pos(1))),...
' [\DeltaX = ',num2str(pos(2)-pos(1)),', \DeltaY = ',num2str((pos(4)-pos(3))),']']);
So, each toggle on the toggle button in the figure will throw in a draggable/resizable line and as I move the line the slope shows and updates, which looks pretty close to what I want. There are, however, two issues:
It deletes all other text boxes except for the very last (current)
text box of the line I'm moving around. I want to keep the last
value remained and shown for all existing lines.
If I delete a line by right-clicking on the line and choose
"delete", it deletes the line, but not the text box and rightfully
so. Now I have a text box that shows the slope of the line that
exists no longer in the figure. I want the text box to disappear
along with the line.
I'm having these problems and really not going anywhere because imline object behaves so much different than other typical objects and also the concept of the addNewPositionCallback is quite convoluted.
Please, somebody enlighten me on this.
Many thanks in advance,
Eric
Previous message:
I create a figure with toggle button on its toolbar by uitoggletool. The callback function for it is shown below:
function calc_slope(handle,event)
on = get(handle,'State');
if strcmpi(on,'on') || strcmpi(on,'off'),
xy=imline;
addNewPositionCallback(xy,#(xy)...
title(['\DeltaY/\DeltaX = ',num2str((xy(4)-xy(3))/(xy(2)-xy(1))),...
'[\DeltaX = ',num2str(xy(2)-xy(1)),...
',\DeltaY = ',num2str((xy(4)-xy(3))),']']));
end
As you can see, the example outputs the position data in the title of a figure using the 'title' command.
Is there a way to output this in a text box using the 'text' command?
I want to display the slope next to the line drawn.
Also, it will be great if the text box also gets deleted together with the associated line.
Please, help.
Thank you,
Eric
Related
I would like to have a text box and a button in my GUI. When the button is pressed, a history window will come up, and if the user selects a previous entry the text that they have highlighted in the edit box will be overwritten.
It should work like copy-pasting, whatever is selected in the history window should be pasted over what is selected, or the new text should be added wherever the cursor is.
Is there any way in Matlab to do this? Is it possible to access what is highlighted in an edit box?
With vanilla Matlab this isn't possible. It appear that Mathworks is in the process of expanding what they support with GUIs (survey 1, survey 2), but as of yet they don't allow this.
One possible workaround is using findjobj.m, by Yair Altman. He discusses edit boxes in this post
You can trace findjobj.m for your text box to find 1 or 2 lines of code that are needed so you don't have to carry around all 3,400 lines of it.
Then all you really need to do is get the selected indices and work from there.
javaHandle = findjobj(editBoxHandle);
startSelect = get(javaHandle,'SelectionStart');
endSelect = get(javaHandle,'SelectionEnd');
Once you have the indexes of what text is selected, it becomes almost trivial to replace that text with the new text.
text = editBoxHandle.String;
editBoxHandle.String = [text(1:startSelect) newText text(endSelect:end)];
One thing to note, when the user clicks the button the text box will lose focus, and it will no longer be clear what text is selected. You can remedy this by giving focus back to the text box, and re-selecting what was selected in the button's callback.
uicontrol(editBoxHandle); %Give focus to the edit box, selecting the entire text
javaHandle.select(startSelect,endSelect); %select/highlight the correct stuff
This will highlight the text that will be replaced with the users selection
I have a very long script in MATLAB (1500 lines) and want to test two different settings. To do so, I need to comment out some codes in a specific interval (e.g. form line 234 to line 255).
Is there a function in MATLAB that takes the intervals and comments/uncomments them automatically?
You can just highlight your code and click on the comment button. Highlight and click on uncomment to remove comment.In windows you may also use shortcut keys cntrl+r and cntrl+t. But yeah, the if else is a better idea but takes more time in the beginning to code in the if else.
I would agree with others that putting your code into a block surrounded by if-else would probably be a better solution than what you originally asked for.
But if you want to do it, you can use the following function:
function commentout(fromline, toline)
currentDoc = matlab.desktop.editor.getActive;
currentDoc.insertTextAtPositionInLine(sprintf('%%{\n'), fromline, 0)
currentDoc.insertTextAtPositionInLine(sprintf('%%}\n'), toline+1, 0)
This will work in most recent versions of MATLAB.
To uncomment, I think you'll need to do something a bit more complex, like getting the entire text from the active document, removing the specified comment lines, then setting the entire text back again (get, modify and set the Text property of the document).
I am new to using the matlab GUIDE. I know there are some predefined dialog boxes such as inputdlg and msgbox and warndlg and so on and so forth that can easily be implemented into the command line without having to play around with too many things.
However, I was wondering whether it was possible to modify inputdlg in matlab guide? I am just trying to produce a simple dialog box that reads the user input and when the user clicks ok, it closes and records the inputs somewhere. Using inputdlg it is very easy to do so:
uiwait(msgbox(sprintf('Please enter your new references for each electrode.')));
prompt = {'Fp1','Fp1','F7','T3','T5'};
dlg_title = 'Input references';
num_lines = 1;
answer = inputdlg(prompt,dlg_title,num_lines );
The user enters a string for each option 'Fp1', 'F7' and so on and all these answers are recorded in "answer".
Now I have 2 problems:
I have 16 such inputs and if I put them all inside the same "prompt" then the dialog box runs off the screen - so I use prompt, prompt2 and prompt3 to split them up and record the answers. It works fine, but it would be better if I could arrange the input boxes side by side as you can edit/drag inside the matlab guide.
I want my dialog box to look as it does in this picture with the minus sign between the 2 cells where the user will enter something into both boxes. The first box in each line is actually equivalent to the prompt that I have specified above, but in this case the user will enter the string into the first cell rather than being prompted for it.
But I can't seem to figure out how to do this either using inputdlg itself and altering its properties or using guide to create a custom inputdlg.
Does anybody have any advice?
Update
I have added some lines of code in the correct places and I am able to now store the user input to a variable. However, I have around 32 edit boxes and my current method means I will have 32 different inputs... I do not want this, I want them all to be recorded inside the same array.
The code I added was in the edit box callback function:
input = get(hObject, 'String')
display(input)
assignin('base','input',input);
% Save the value
handles.trial = input
guidata(hObject,handles)
This is from editbox1 and I have tried to proceed as
input = get(hObject, 'String')
A(1,:) = input
assignin('base','A',A(1,:));
but in this case it returns A as a cell which has the value entered in the last edit box.
Can anyone help?
First you should make matlab wait for the user to respond. Locate the OpeningFcn of you GUI. The last line should look like that
% uiwait(handles.figure1);
You should uncommon the line. Next, you have to resume the UI when the user clicks OK. This is done by inserting the line
uiresume(handles.figure1);
in the OK button callback. When the users clicks OK, the OutputFcn will be called. There you can return the values you need via varargout cell array. Finally, in the last line of OutputFcn, you should close your GUI using
close(hObject)
All the names I used are the matlab's defaults. If you changed any of them, modify the code accordingly.
I think it should be pretty simple what I want to do, basically I have one edit box that displays a value in percentages and another that I want to update to display raw values. I've tried using the following code under the edit1 (percent) callback:
currentKey = str2num(get(gcf,'CurrentKey'));
percent = str2num(get(handles.edit1,'String'));
if ~isnan(currentKey) && ~isnan(percent) && 0<=percent && percent<=100
set(handles.edit2,'String',num2str(2*percent))
end
But it will only update the second edit box if I first click outside of the first one. Anyone have an idea of what I should be doing?
Thanks!
I think this link should help you:
How can I make the text that I enter into an edit text box update dynamically?
Solution:
This enhancement has been incorporated in Release 2011a (R2011a). For previous product releases, read below for any possible workarounds:
This is expected behavior of the Edit Box UICONTROL in MATLAB.
You can try using the 'keypressfcn' to grab the keyboard input. The attached two files demonstrate the ability of real-time text update. As you enter text into the upper edit box, the text will be copied to the edit box beneath it as you enter.
Please download the following two files:
test_keypressfcn.m
test_keypressfcn.fig
Execute the program.
A GUI will appear. Enter text in the upper edit box displayed in the GUI.
Observe the text in the lower editbox is updated dynamically or in real-time as you enter test in the upper edit box.
Please note that this will work only for text that is continuously entered in the editbox. If you type in between words already entered in the editbox the gui will not perform as expected. You will need to implement logic similar to the one in this example to get the behavior that you desire.
I have a MATLAB program I am developing in order to do some image processing stuff and need to use a user control into a MATLAB GUI user interface I created ad-hoc.
This user control is a List Box and there I would like to insert some text. Well the problem is not that I cannot put text there, I can do that using this call:
set(handles.mylistbox, 'String', 'MyStringToPrint');
Well the problem is that this call does not let me insert many lines in my list box but just overwrite the previous one.
I wish to find a way to let my code insert the new text in a new line. This should not be so difficult to do and it is also a simple pattern:
texttoprint = 'My text to add'
oldtext = get(handles.MyListBox, 'String') %Holding the previous text here
set(handles.MyListBox, 'String', [oldtext '\n' texttoprint]) %Setting (no line feed printed)
set(handles.MyListBox, 'String', [oldtext char(10) texttoprint]) %Setting (this fails too)
Well it is ok and it does not raise any error BUT, \n DOES NOT WORK.
I do not have any new line... BUT NEED TO!!!!
How should I solve this?
The problem is that I need to print text in this user control, not on the MATLAB commandline (that is very simple just by doing sprintf()).
What to do? Thank you
For a listbox, set the string property to a cell
set(myListboxHandle,'String',{'myFirstLine';'mySecondLine'})
If you want to add another line, call
contents = get(myListboxHandle,'String');
set(myListboxHandle,[contents;{'another line'}])
For multiline text in GUIs otherwise, use char(10) instead of \n, i.e.
set(someUiControlHandle,'String',sprintf('my first line%smy second line',char(10)))
When working with list boxes it's usually easier to deal with the options as a cell array of strings. So, you would initialize your list box as follows:
set(handles.MyListBox,'String',{'Option 1'});
And then you can add options to your list box like so:
newOption = 'Option 2';
oldOptions = get(handles.MyListBox,'String');
set(handles.MyListBox,'String',[oldOptions; {newOption}]);