Generate a Window from Core Data - cocoa

To start, I put my info into Core Data and I have my table showing up in Interface Builder. It has 20 atributes that are the same except for the number after them ie. example1, example2, etc. Each of these atributes has 12 items for the user to change with 3 variables each(on,off or random).
I want these choices for the user to change to come up in a new window. I don't want to bind each of these variables by hand! Is there a way to bind the whole window?
And should I use an interface builder plugin and make a master window or make 20 windows or ??? I'm a complete novice, but would like to do this the best way.

It sounds like you just need to change UI labels/column-titles. If so, you can bind the text of the label to either data or an attribute of the controller that configures the label for the current state of the data.
If you have repeating units of data, you can define a cell which is bound to a controller and then use as many instances of the cell as needed. See NSMatrix and related containers.

Related

Python gui table whose cells are drop down lists with dynamic content based on the content of other drop-down-list-cells of the same gui-table

I am trying to port to Python 3.x a small gui application that I have written in Matlab.
The app contains a Matlab uitable, with which you can program bitfields of registers of a microcontroller. Actually you can create a panel which groups some register-bitfields that are important to you for debugging at a specific point in time (kind-of a watch window in a compiler IDE).
It looks like this:
Gui Table used to write to register bitfields of a microcontroller
So, each row of the table can be used to program a specific register bitfield.
There are 4 columns:
1. Register name (drop down list)
2. Bitfield name (drop down list)
3. Value to write (string)
4. Format (Hex or Dec drop down list, irrelevant here)
In order to use this application, one first clicks on the register name drop down list, where all registers are shown (detail: using a text box one can apply filters to narrow down the list size).
When the register is selected, the drop down list of the bitfield column updates automatically so that it contains only the bitfields of the chosen register. This happens with the help of a callback function.
Then, the user has to enter a value and a format, and only if all cells contain valid content, then a register write command is issued (via some debugger interface).
This worked OKish; sometimes the bitfields list was actually the one of the previous register added in the table, but this could be detected and have the entry cleared so that the user can try again. Also when the number of rows becomes very high and scroll bars appear, then if the user tries to enter a register at the bottom, every time they click on the drop down list, they can choose an entry and then the scroll bar position will automatically change showing the beginning of the table. This makes the process of entering registers quite cumbersome. As far as I know, the uitable of Matlab did not have accessible properties to control this behavior.
Since I am a hw engineer with limited sw technologies knowledge, I am wondering if there is a natural way to support this in Python 3.x, say with some structured (e.g. xml) data container that can naturally map to a gui component, without so much callback programming and data validation. The ideal behavior would be that the user starts to type directly at the register name drop down list (not possible in Matlab), and dynamically gets a filtered version of the register names list.
I am completely new to python, just installed Anaconda. I have found some interesting classes in PyQt:
QListView Class,
QListWidget Class,
QTableView Class,
QTableWidget Class.
However, I would like to have the combined functionality of the tableview with a listview, as is the case with the uitable in Matlab. Or even better, a text edit input that turns into a drop down list after typing a few letters.
The pyqtgraph.tablewidget seems to augment the functionality of QTableWidget, but I think this is still not what I need.
So, if the above is not possible, or would involve heavy programming, maybe all I need is to change approach and have a single separate search box with autocompletion, which looks into a "flattened" version of the registers database, and returns results in the form my_register_1.my_bitfield_1 (maybe allowing the user to search simultaneously at both register and bitfield names). When the user clicks on one item of the "autocompletion list", then the selected entry is mapped to the currently selected line in the tableview, adding both the register name and bitfield in read-only table cells. The "value to write" cell should still be editable, and when it gets valid data it should trigger register write command...
I would appreciate if you could guide me where to look. Thanks!
You should use the Qt model/view architecture. This allows you to have a representation of your data (the "model"), which is separate from how that data is represented (the "view"). So you set up a table of data, and then set up a view to represent that data. When you switch between different data sets, you tell the view to display the new data set. The tutorial I linked to explains this in some detail

NSOutlineView grouping via bindings

This is sort of a best practice question, since I can think of a few ways that would work.
I want to implement an outline view. Let's suppose I want to implement the one in OmniFocus (my aim is very similar):
(I refer to the outline view in the main pane of that screenshot, not to the sidebar.)
So my data type is a task. Any task can have subtasks. Each task has one or zero parent tasks. Classic data model for displaying in an outline view, right?
BUT! I would like to offer the user the ability to group these tasks visually by a property of their choice. They could group them by milestone, or by assigned user, or by component… there'll be a bunch of these. And this grouping should appear in the outline view, at the top level of the hierarchy, just like the "Inbox", "Home" and "Work" items in this OmniFocus screenshot.
So it's fairly obvious that to display the grouping, I should use the built in NSOutlineView methods for drawing a group cell: the outlineView:isGroupItem: delegate method. The problem is, this setup is assuming that each item in the outline view is represented by an item in whatever data model I've connected it to: so both my tasks and my group headers have to be represented in the data model.
Therefore, just binding to the Core Data table that represents my tasks is a no-no. I could forego bindings all together and just go back to the old style data source methods, but then I lose a bunch of useful stuff. So is there a middle ground?
I could, for example, create another class TaskTemporaryGroup. I give that class an ivar NSSet that is subtasks, the same key path as could be used on a task to get its children. Then I can bind my set of TaskTemporaryGroup objects to a tree controller, and it'll arrange the whole tree regardless of the fact that the top level items are a different class to those lower down. I'd have to take care when implementing drag and drop, to make sure that the grouping rows can't be arbitrarily dragged about, but it might work.
The other point of contention is that I would like clicking on the table headers to sort the rows within each group, but not to sort the top level groups. I assume NSTreeController applies the sort descriptors to each level of the hierarchy? I could have my TaskTemporaryGroup class return the same thing (i.e. its desired sorting order, that I've calculated separately) for any of the key paths that I want to be able to sort the rest of the cells on, so that to the framework it would look like they stayed in the same order no matter what property they were sorted by. Is this a good way to go or is it a hack?
So, to summarize:
How do people suggest I implement this kind of hierarchy, where the top level is a special case and all subsequent levels are the same kind of object?
Is the way I described, with a class to represent the top level objects that happens to respond to the same key paths as the child objects, a good way to go?
Does anyone have any tips about how to make sorting work well in this scenario?
Or will trying to use bindings for this task cause me a world of hurt?
Thanks,
Amy

Can i change the view without changing the controller?

Pretend1 there is a place to type in a name:
Name: __________________
When the text box changes, the value is absorbed into the controller, who stores it in data model. Business rules require that a name be entered: if there is no text entered the TextBox should be colored something in the view to indicate baddness; otherwise it can be whatever color the view likes.
The TextBox contains a String, the controller handles a String, and the model stores a String.
Now lets say i want to improve the view.
There is a new kind of text box2 that can be fed not only string-based keyboard input, but also an image. The view (currently) knows how to determine if the image is in the proper format to perform the processing required to extract text out of it. If there is text, then that text can be fed to the controller, who feeds it to the data model.
But if the image is invalid, e.g.3
wrong file format
invalid dimensions
invalid bit depth
unhandled or unknown encoding format
missing or incorrectly located registration marks
contents not recognizable
the view can show something to the user that the image is bad.
But the "telling the user that something is bad" is supposed to be the job of the controller.
i'm, of course, not going to re-write the controller to handle Image based text-input (e.g. image based names).
a. the code is binary locked inside a GUI widget4
b. there other views besides this one, i'm not going to impose a particular view onto the controller
c. i just don't wanna. If i have to change things outside of this UI improvement, then i'll just leave the UI unimproved5
So what's the thinking on having different views for the same Model and Controller?
Nitpicker's Corner
1 contrived hypothetical example
2 e.g. bar code, g-mask, ocr
3 contrived hypothetical reasons
4 or hardware of a USB bar-code scanner
5 forcing the user to continue to use a DateTimePicker rather than a TextBox
I think you've touched on the very essence of MVC programming: Ideally, when you change the view, you shouldn't have to change neither model nor controller. However, what you are writing here is basically an adapter for the controller (as you can't change the controller), so you need a secondary controller to turn your image (or whatever) into something the controller can understand.
Or in other words; the View is just the code to draw the frame that the image is displayed in while text is being extracted, the image->text adapter is actually a controller.

Custom editor in QAbstractTableModel

Does anyone have an example of using a QWidget as an editor in a QAbstractTableModel?
I have a column which when edited should create a QCombobox with the list of choices.
The docs seem to suggest I need to write a QAbstractItemDelegate and a custom paint function but that seems overkill to simply pop-up a standard QCombobox in Qt::EditRole.
Note - the combo box contents are the same for every row and it only needs to be shown when somebody clicks in the cell.
I know this should be simple but I can't get it to work. It's easy for a QTableWidget based table - but I need it for a very large data table.
The docs seem to suggest I need to write a QAbstractItemDelegate and a custom paint function but that seems overkill to simply pop-up a standard QCombobox in Qt::EditRole.
You don't need to go that far. One way is to subclass QStyledItemDelegate and then override createEditor() so that it returns your prepopulated combo box. Its setEditorData and setModelData functions will probably already suffice if you`re using basic Qt value types.
If you need something more generic that works across many different models, you can create a QItemEditorFactory that associates your editor with the correct type. This also works well with custom types.
When indicated by your view's EditTrigger, your view will get the delegate specific to the cell on which the edit is being invoked and call delegate->createEditor(...) which can then size the combo box according to the options parameter as well as set the current entry to the value specified by the model, although most of this should be handled by the QStyledItemDelegate. Thus, you won't have to worry about the Qt::EditRole directly as the view will handle that.
Did you try and have a look at the following example from Qt :
Spin Box Delegate Example
Maybe it will give you a much clearer view on the subject !
Hope it helps a bit !

What's the best way to add a composite property for binding to an existing class

Let's say I have a Size class which has height and width properties (in reality the class is a bit more complex than this, but Size makes a good example).
I want to display this as $width x $height in my UI.
The obvious way to do this is to bind to a dimensions property which is dependent on width and height.
My question is where is the best place to add this new property?
I could add it to the Size class itself in the modal, but then if another controller wants to display the string different I'm stuck creating yet another property. I'm also a bit reluctant to do this because in my case the Size class is in a framework that will be used in a couple different places (although likely all from code I have control over).
I could add it in a category to the Size class inside the project containing the view/controller so it will only be availiable in the places I know it will be used, but in various places I've seen suggestions that categories tend to be overused, and am forced to wonder if this is one of those cases.
In the case of a single Size instance I could create the property in the controller class containing it, but this becomes more difficult when you have an array of Sizes.
I could bind to the entire size object and use a transformer to turn them into strings, but binding to an array of sizes would then cause you to have to transform each element of the array into a new array in the transformer, which seems a bit ugly.
If want to display this composite value as a string, then bind "Display Pattern 1" of a text field to the width property and "Display Pattern 2" (shown when you bind Display Pattern 1) to the height property. In the Display Pattern 1 binding, set the "Display Pattern" to %{value1}# x %{value2}# (yes, slightly unintuitive syntax). This will give a text field that displays "[width] x [height]" and will update on changes in either property.
You can do the same with an NSTextFieldCell, e.g. as the cell in an NSTableColumn. The downside of this method is that the text field will not be able to edit the bound width and height values. You would have to write an NSValueTransformer if you need to be able to edit them.
Using multiple bindings through a display pattern as Barry suggested sounds like the best approach, at least without knowing more about your UI. I've used the same thing in the past, where I built an inspector for an array of images and had the dimensions bound to a single text field.
In general it's good practice to use value transformers or formatters if you can, but in cases of last resort there's nothing wrong with using a category. I've done this in the past when I had trouble binding to a date, but breaking it down into individual time and date pieces. A category is a good approach because it lets you maintain separation with the model, but you don't need to do anything crazy like binding directly to the controller.
I want to display this as $width x $height in my UI.
Why not two fields? Then you could make them editable.
(in reality the class is a bit more complex than this, but Size makes a good example)
Assuming the above is not feasible in your real situation, you might try creating a custom subclass of NSFormatter, and setting it as the formatter on the cell (I assume this is in a table view, since you wouldn't bind a single control to an array). You would then bind to whole Size objects.

Resources