Specify What to Edit for User
3 次查看(过去 30 天)
显示 更早的评论
I'm writing code which should allow the user to edit certain sections, and I want to make it clear to the user where they should edit (it doesn't have to prevent them from editing other stuff). The user would select what they want to modify in the code (through a GUI) and it would take them to the correct section of the code. I thought of a number of options (unfolding only that section, disabling editing other code, moving to the correct line) but I couldn't find a command to do any of these things. (Having it display something in line through live editor won't work because it's a class). Does anyone know how you might implement this?
26 个评论
Guillaume
2019-7-10
Replicating a code editor in a matlab GUI would be a significant undertaking and I'm not even sure that it would be possible with the controls that matlab currently offer.
If I were going to build the kind of GUI you describe, I certainly wouldn't do it in matlab. I'd use a language where you can use already made code editor controls such as scintilla
On the other hand, forcing users to edit code doesn't sound like a good idea.
Ephraim Bryski
2019-7-10
编辑:Ephraim Bryski
2019-7-10
SeeI think I should have been a bit clearer. I already have the bulk of it down I think. Now the user would just have to manually find where in the code they should edit. All I want to do now is make it a bit easier for them to figure it out. They would just be adding properties into a class, but I want to make it easy for them to know where they should add that property. Basically I just have different kinds of properties in different sections and I would want it to be clear where they should edit.
Guillaume
2019-7-10
You already have a GUI that allows users to edit code?
Allowing users to extend a class by editing the class directly is very much against OOP principles. You normally use inheritance to extend classes.
Ephraim Bryski
2019-7-10
编辑:Ephraim Bryski
2019-7-12
The user would do fairly basic things (also for now I'm the user). For example there are properties for physical constants but the user might want to add some more properties. The idea is the user is writing their own code to create a class. I just have it set up to make it easier and already have some properties included.
The main purpose of the GUI is also not to help them add properties. It's mainly to provide an interface for them to call functions which use those properties. I could instead require the user to just manually go the right section and write their code and it would work essentially the same way.
EDIT: I finished writing a very rudimentary code which allows users to create their own constants (properties) and parameters (methods). Right now there's a single class which has everything, but if I were to make it more general, I think it would make sense to make subclasses. There would be a main class with fundamental things (like physical constants). Then there would be subclasses (and then maybe subclasses with in subclasses) which are more specific. The user would be able to create a subclass with constants and parameters specific for their project. Because I'm working on a single project, that's not very useful for me to implement right now though.
Guillaume
2019-7-12
I'm still not completely clear on exactly what help you're asking for. You said you already had the bulk of it done. The bulk of the GUI? As I said, I don't think it's possible to make a proper code editing GUI in matlab, the text control it offers is too basic.
In any case, if I was to make a GUI for user to specify some properties and call functions on them, I wouldn't ask them to do that in code. I'd use a UItable or similar so that the only task they have to ensure is that the property names and values are correct and that they've selected the correct function, rather than also having to ensure that the syntax is correct and that the code they've written stay within the boundary of what's allowed by your architecture.
Ephraim Bryski
2019-7-12
编辑:per isakson
2019-7-30
I didn't mean the GUI, but the system of using classes to store constants as properties, parameters as methods, and types of plots as functions which get instances of the GUI and the class containing constants and parameters. If I made a table, it could be used to add numerical constants, but I think that's all. The point of the program is to seamlessly integrate the code the user writes with the rest of the program (that's essentially what the program is). I actually wrote about the program here:
Guillaume
2019-7-12
Ok, reading about your description in that other post, I think your GUI should simply be matlab. And instead of making your own GUI, you should provide good documentation of the API.
Otherwise, I fear you'll be trying to replicate most of matlab editing facilities within a matlab GUI, which as I said, is not really feasible.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
Thank you very much for the advice! Yes, I was considering removing the GUI altogether, but I thought it would too hard for the user to access things without it. For example, now there's a drop down which lists all the functions (associated with types of graphs) which the user could select. It searches the directory where plot functions are stored and adds the name of all the functions to the list. Then when you create a new function you save it in the directory so it automatically adds that function. I don't know how I would implement something like that without a GUI (of course they could just call the function but then they would have to get the name just right). I could even allow them to start typing the name of the function and it would find the ones which start with that name (I have NOT implemented that yet, but I don't think it would be very hard).
The GUI is designed to do as little as possible. The only code within the GUI is to disable certain buttons (for example if I want to save figures I would want to disable the field which selects which trial to iterate through but iterate through all of them), code to call refresh (which refreshes the drop down), a call (I actually use run) to the selected function, a command to open the class, and a command to open the template function
As for API, I don't know what to say about that because I honestly had to search it up to find out what it means. I'm essentially learning all this stuff as I make the program. I've only been working on it for two weeks and it's basically been a constants process of learning about coding, figuring out what would make sense to implement, and then implementing it. For example, a few days ago I only had a very crude idea of what classes even were.
Stephen23
2019-7-12
编辑:Stephen23
2019-7-12
@Ephraim Bryski: you seem to be putting a lot of effort into essentially replicating MATLAB functionality: e.g. adding functions to the Search Path, function name hints, listing functions,...
"...they could just call the function but then they would have to get the name just right"
At some point you have to trust your users. Providing a walled-compound for your users, within which every little operation is carefully micro-managed and restricted, might possibly be achievable, but the code will be bloated, fragile, and difficult to maintain. And user-unfriendly.
As Guillaume wrote, providing good documentation (and input testing) is more useful than forcing your users into interacting with your code in one particular way. If you want the users to be able to add functions, then give them that responsibility: let them supply function handles as input arguments, or they can change the search path by hand, or whatever. Document it clearly, and throw an error if they do not do it properly.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
I think I see what you mean. The user could instead just search for the function (maybe just by clicking the open button) find the function and then run it. (Edit: I realize now this is NOT what you mean). To be fair though, the refresh function is only 10 or so lines.
Also there's no code to add the function to the search path. The user just selects the right folder to save it in it. This would enable them to make different folders (by this I mean actually making folders as you normally would) where different types of functions to create plots is stored.
As for the function hint, I was not thinking of implementing it any time soon, and after discussing it with you, I guess it might be better not to.
Ok for docoment I imagine you mean something detects what the search path is (for example) and then can return an error based on that. I'm still not sure how I would implement that though.
As for making a function handle an input, I don't quite get what you mean. So there are two functions you're referring to, one with a handle as an input, and one being the function whose handle is being inputted. What would these two functions be? (When searching up the documentation for inputting function handles it only lists built in functions and antonymous functions so I'm also not sure how I would use it). https://www.mathworks.com/help/matlab/matlab_prog/pass-a-function-to-another-function.html
Guillaume
2019-7-12
编辑:Guillaume
2019-7-12
"As for API, I don't know what to say about that because I honestly had to search it up to find out what it means"
Application programming interface. You've defined a set of classes which must adhere to some structure, and you've defined a set of functions that must be called with some particular input and will return some particular output. That's the API of your code. By documenting it, you're telling your user, if you call this function with these arguments, you'll get this result. If your class has these particular properties, then it will work with my functions, etc...
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
Oh, I think I get it now (tell me if I'm right). The handles would be methods within a class and the function with handles as inputs would be what create plot types. I think that makes it a lot easier to understand what you mean by documenting, and I think that makes sense. I still don't know how I would implement it, but I'm sure I could figure it out. (Do you know of any websites which describe how to document; the only things I could find describe what it is. At the very least is it something I would have to learn or is it something I could implement through sheer ingenuity)? Also, thank you for putting a word on what I'm making (I can now say a super basic API instead of something which allows the user to do stuff).
Also, to be fair I only have one class now (although I would add more which inherit from one another if I were to generalize it). Would this still be an API?
Stephen23
2019-7-12
编辑:Stephen23
2019-7-12
"Ok for docoment I imagine you mean something detects what the search path is..."
Not at all. I mean that you should write clear documentation that specifies exactly what inputs and outputs your code has, what other specific requirements it has, explains how they can expect it to behave, and gives some examples of its usage.
I would not "detect what the search path is" unless I was writing a "detect the Search Path" tool.
Ephraim Bryski
2019-7-12
Yes that was and outdated version of my understanding but I think I'm starting to get it now and that clarifies it even more
Guillaume
2019-7-12
Would this still be an API?
The API is basically a contract between your code and the user. You tell the user: to achieve this task, you use this function/class/whatever with these inputs, and you get that in return. As long as they follow the contract, everything works (baring bugs), if they don't stick to their side of the contract (supplying required inputs that follow the contract), then they're outside of the API and shouldn't have any expectation that anything work (it may or may not). The API can be made of many functions/classes or just one.
You don't have to call it an API. What is important as Stephen and I said, is that you document your interface. See the matlab documentation for an example of fairly good documentation. An important part of a documentation is explaining what your function expects as input and how that affects the output. Writing good documentation requires some effort. However, undocumented code is useless to anybody but the author (and even then, 6 months later the author may have forgotten).
Note that documenting your API includes specifying what class of inputs are expected (numeric, string, char array, cell array, logical, etc.), what shape is allowed (scalar, row vector, column vector, matrix, ND array, etc.). Same for outputs. Using validateattributes at the beginning of a function is a good way to check that the user is conforming to your contract.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
Alright I think that makes sense. So basically I was currently "documenting" by writing comments explaining what to do. This worked for me as the user because I already know how it works and it's very rudimentary, but would become a terrible idea if others were to use it. So to make it more robust I would have to actually include errors within the code if the user doesn't do something right and some way of directing them to use it properly. I'm not sure how to do that yet but if my mentor is ok with me generalizing it I will definitely work on that (it seems to make a lot of sense). Also, how would I go about directing them? Being naive I imagine using disp but I don't think that's what you mean.
Stephen23
2019-7-12
"...include errors within the code if the user doesn't do something right"
Actually disp is not so far from the answer: use error and assert and warning as required. Check that inputs meet your specifications using your own checks or an input parser.
"Also, how would I go about directing them?"
Throw an error if something happens which your code should not handle, with a clear error message explaining the cause of the error. You do not need to "direct" them to read your documentation, which they should be doing anyway.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
Again I'm going to ask something kind of naive. Where will they read it (or essentially where will I write it)?
(As a side note, I have sort of noticed the errors from Matlab have sort of become documentation to me as I developed it. They now direct to exactly where my error is through the functions I wrote which I took as a good sign and made it much easier to develop. I never got an error which I didn't understand -- and the time required to understand it has steadily decreased).
Also, as a bit of a side note is there a way of changing the variable name of an object through all my code (instead of just a single function). As a simple example, if I wanted to change the name of a switch in the gui I would have to manually go through my entire code. It's easy but extremely annoying and makes me very wary of changing variable names even if the new one makes more sense.
Stephen23
2019-7-12
编辑:Stephen23
2019-7-12
"Where will they read it (or essentially where will I write it)?"
The simplest is simply by adding a help section at the start of functions (which can then automatically be shown in a browser/dialog similarly to MATLAB's own help):
or in HTML/whatever documentation created using publish:
or using much more sophisticated toolbox documentation:
or by providing demo scripts, or whatever suits your workflow.
"...is there a way of changing the variable name of an object through all my code (instead of just a single function)"
Not really.
But the variable name really should not matter anyway: variable names used inside any function should be totally irrelevant to the outside world. There is no reason why the name of some value should be the same in every different function workspace, just pick names which are suitable and relevant for each function.
Ephraim Bryski
2019-7-12
Oh wow! I basically already did the first option if adding comments in it is all it is.
Guillaume
2019-7-12
At the most basic, documentation can be just comments at the start of the function or within the class. Later on, you can do something more fancy (follow the links at the bottom of that documentation), or write your documentation as a Word/PDF/whatever takes your fancy.
Here is an example of class documentation that I'd consider good. You can see that the DrawText method relies on an inputParser to check that the user conformed to the documented API.
classdef (Sealed) ImageCanvas < handle
%ImageCanvas: Allows drawing text and shapes onto images
%All the drawing is delegate to .Net, so this only works on Windows.
%
%In order to draw on an image, it must first be converted into a canvas.
%All drawing is done onto the canvas, and when needed, the canvas can then be converted back into an image
%Note that canvas are always 8-bit true colour images. Original images in other format will always be converted to that format
%A canvas is created simply by passing an input image to the ImageCanvas constructor.
%
% canvas = ImageCanvas(someimage);
%
%Member methods of ImageCanvas can then be called to draw on the canvas.
%All drawing methods will require at least one of the following object as well(unless defaults are used):
% Font: for text drawing methods, specify which font and font style to use.
% Brush: for any drawing with filled shapes (including text), specify colour and texture of the filled shape.
% Brush has several derived implementations:
% SolidBrush: A basic brush that fills the shape with a solid colour.
% HatchBrush: A brush that fills the shape with a hatch pattern.
% Pen: for drawing anything with lines, specify the colour, thickness, endpoints, etc. of the lines
%
%To retrieve an image, after having drawn on the canvas, call GetImage:
%
% newimage = canvas.GetImage;
%
%The width and height of the canvas can be queried at any time, it's the same width and height as the input image:
%
% width = canvas.Width;
% height = canvas.Height;
%
%The following methods are currently implemented:
% DrawText(Text, Location, name, value...): Draw text at specific location.
% Text The text to draw on the image. char row vector or scalar string.
% Location Location in pixels of the upper left corner of the text box as a 2 element vector [x, y] of any numeric type. Coordinates are .Net based. Upper left corner of the image is [0,0]
% The following name/value parameters are available
% 'Font', font Use the given font to draw the text, can be a Font object or a .Net System.Drawing.Font object. If unspecified, matlab's default font is used.
% 'Brush', brush Use the given brush to draw the text, can be any Brush derived object or a .Net System.Drawing.Brush object. If unspecified, a solid black brush is used.
% 'BoxSize', [width, height] Clips text to box size in pixels. If not specified the text is clipped to the image.
%
[...] code removed
properties (Dependent)
Width; %Width of the canvas. Same as the original image.
Height; %Height of the canvas. Same as the original image.
end
methods
function this = ImageCanvas(image)
%Construct an ImageCanvas from an image
%the image is stored as a truecolour 8-bit image
% canvas = ImageCanvas(image)
% image: 2D or 3D numeric matrix. if double, intensities must be in the range 0-1. Indexed images are not supported
[...] code removed
end
function DrawText(this, varargin)
%Draw text onto the canvas
% canvas.DrawText(Text, Location, name, value...)
% Text The text to draw on the image. char row vector or scalar string.
% Location Location in pixels of the upper left corner of the text box as a 2 element vector [x, y] of any numeric type. Coordinates are .Net based. Upper left corner of the image is [0,0]
% The following name/value parameters are available
% 'Font', font Use the given font to draw the text, can be a Font object or a .Net System.Drawing.Font object. If unspecified, matlab's default font is used.
% 'Brush', brush Use the given brush to draw the text, can be any Brush derived object or a .Net System.Drawing.Brush object. If unspecified, a solid black brush is used.
% 'BoxSize', [width, height] Clips text to box size in pixels. If not specified the text is clipped to the image.
%
parser = inputParser;
parser.FunctionName = 'ImageCanvas.DrawText';
parser.addRequired('Text', @(text) validateattributes(text, {'char', 'string'}, {'scalartext'}));
parser.addRequired('Location', @(location) validateattributes(location, {'numeric'}, {'numel', 2, 'nonnegative', 'finite'}));
parser.addOptional('Font', Font, @(font) validateattributes(font, {'Font', 'System.Drawing.Font'}, {'scalar'}));
parser.addOptional('Brush', SolidBrush, @(brush) validateattributes(brush, {'Brush', 'System.Drawing.Brush'}, {'scalar'}));
parser.addOptional('BoxSize', [], @(boxsize) validateattributes(boxsize, {'numeric'}, {'numel', 2, 'nonnegative', 'finite', 'real'}));
parser.parse(varargin{:});
[...] code removed
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
I'm still a bit confused. So just to keep on using switch as an example. The function could get a handle on the switch object and call it whatever I (the coder) wants. But when you get the handle won't you still need the variable name of the object? Ah I think I get it now. The handle would be created in the very beginning so it doesn't matter much the user won't have to look at it
Stephen23
2019-7-12
编辑:Stephen23
2019-7-12
"...won't you still need the variable name of the object?"
I think I misunderstood your original question due to the terminology: objects have methods, properties, and events, but they do not have variables:
I was using the standard MATLAB terminology, where a 'variable' refers to an instance of some class (I have never used any OOP language where the term 'variable' refers to a class attribute).
I suspect that you wanted to ask "... won't you still need the object's property/method name?" , in which case the answer is "yes". If you meant something else, please explain.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
Yes, that is exactly what I meant. I'm still very new to this, so my terminology is pretty lousy. When I say variable name I meant any thing where you would say
(my idea of variable name)=(something)
I realize that's not correct now though.
This is a very specific question, but important for me and may help me improve the overall code. I'm supposed to make an animation, but when I run it it's incredibly slow now that I've implemented it (like it would take hours to finish slow). I made inputs to the function where all the inputs are handles (to clarify:
if I were to type the input into the command window it would give:
(my_input)=(something (cell array, matrix whatever))
)
so inputting it should NOT
require it to access the class. I'm not sure what is causing it to be slow (but I'm supposed to update the animation -- change the annotation a bit -- and show it to the mentor today) so I really need to figure out what could be wrong. Saying my program causes it to be really slow wouldn't be that good.
Ephraim Bryski
2019-7-12
编辑:Ephraim Bryski
2019-7-12
So I think the idea is I would create the API and the user would basically have to learn how to use it. There would documentation they could get with help (some name of my function) and it would throw things like warnings or errors if they're not using it properly (the API would somehow have to know what the users trying to do and decide if it's ok).
I think I'm going to save some new code which doesn't have any of the specifics for my project (so you don't have to look through hundreds of irrelevant lines of code) add some very basic documentation (at least some stuff you could access with help) and upload it to an opensource forum. Then I'll add the link here and anyone who wants to can edit it. I think I'll keep the GUI but the first step might be getting rid of it. Hopefully I'll have it uploaded by Monday or so.
I do want to make this specific for water related stuff (things like experiments where waves impact objects) so certain specific code (like calculating uplift from pressure gauges) would also be uploaded.
Ephraim Bryski
2019-7-13
I thought about all this and I described how the api should work here. I still have to learn a bit more I think before I start coding (things like handle functions, handle functions as inputs, assert). I also don't know how good my basic idea so far is.
回答(1 个)
Image Analyst
2019-7-12
I'd just use app designer or guide and make a gui with either 3 radio buttons or a drop down list (popup) with three selections. Then in the main part of your code, you can check the state of the GUI controls to see which of your available options they selected.
4 个评论
Image Analyst
2019-7-12
If you need an example, see MAGIC: https://www.mathworks.com/matlabcentral/fileexchange/24224-magic-matlab-generic-imaging-component
Ephraim Bryski
2019-7-12
I think my initial question was not very clear. However Guillaume started a comment in which we discuss it in more detail.
Image Analyst
2019-7-13
I still think you're making it way more complicated than necessary by doing such low level API coding manually.
Ephraim Bryski
2019-7-13
If you're referring to the GUI, I decided the first thing I'll do is get rid of it.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Software Development Tools 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom(English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)