I don't understand how QAbstractItemModel works - c++

I've been using this class somewhat successfully thus far but I feel like I don't have a good conceptual understanding of what I'm doing. I'm missing something basic about the Qt model/view architecture which prevents me from making full use of it. Qt doc doesn't seem to be addressing my questions. Much of my lack of understanding seems to be centered around the data() method.
For example:
1) The doc doesn't properly explain (or I missed it) what the data() method is and how to properly use it. I just have this vague idea that it is some kind of callback or slot function for when there are any changes to my model. But architecturally speaking what is its role? Why is it needed and what problem is it solving?
2) Speaking of roles, what is the point of the role parameter in the data method. Again, why did the designers choose to implement the data() method this way?
I hope my questions aren't too abstract. If they are it might be because I don't fully understand what I don't understand about the model/view architecture. Therefore not quite sure how to formulate my question.
Anyway, anyone who has some decent understanding of these concepts is welcome to chime in. Also if anybody knows other places that explains this better than the Qt doc that would be great as well.
Thanks much for any feedback.

As the function name hints the `QAbstractItemModel::data()' is for providing the information that should be visualized by the view. View doesn't need to cache all the data (in some cases thousands of elements) at once, but incrementally queries it from this function as soon as it should be shown on the screen.
When I talk about the data, I assume that it could be item's text, text color, background color, icon etc. All these types of data represented by Qt::ItemDataRole enum and the data itself represented by QVariant.
For example, if you have a tree view and corresponding model. When you scroll the tree down, it should paint, say 20 nodes. Tree view calls model's data() function for each of these 20 nodes to paint their texts, icons, backgrounds etc.
And finally, for better understanding roles. Instead of having textData(), colorData(), iconData() function in the model, Qt provides one single function data() with ability to conditionally chose which data to return depending on the role. This is much convenient design wise.

Did you read about Model/View Programming?
http://doc.qt.io/qt-4.8/model-view-programming.html

Related

In Figma: How to specify layouts for CSS grid systems?

Summary: I have seemingly hit a limitation in Figma when trying to make the columns behave akin to a CSS grid system. I would like to know if I have misunderstood Figma's built in capabilities, if there is a plug-in that solves the problem, if I have to create one Figma frame per CSS breakpoint (undesirable), or if there are other solutions.
Background: As an interaction/ UX designer, I would like to specify the responsiveness of a web based application, so that the front end developers know how the interface should appear at all browser widths. They implement in a CSS-based grid system similar to Bootstrap
So far, I failed in achieving what I want, and the most knowledgeable UX'ers in the company think I have hit a limitation in Figma's capabilities, but they are not certain.
Basically, what I want is this basic responsiveness, but column based. But as shown in this video, none of my experiments work.
I wonder if it boils down to this: If a Figma child element has:
horisontal constraint set to “Scale” and
vertical constraint set to “Hug contents”
Then the parent element cannot have:
vertical constraint set to “Hug contents”
Is this is a known limitation in Figma? If yes, are there plugins that solve this problem, or is it outside Figma's scope to offer this type of alignment with CSS-based grid systems? Obviously, it would be very beneficial if the solution also supports breakpoints.
P.S. I have asked which SE site that was most suitable for this question, and SO was the suggested site. The question was closed on UX.SE.
No, according to an answer on Figma's own forum, Figma's columns cannot behave akin to a CSS grid system, even though “several threads [have] requested [this] evolution”.

Qt QML: UI with dynamic number of images provided by c++ code

I am designing an application that, in essence, gets a number of images (which change - think of several videos consisting of many images each, displayed in sequence) which I want to display in a grid pattern. This pattern should be extensible, I want to be able to control row and column count dynamically.
A C++ core application provides these images at varying speeds. It needs to know where to send them.
My team and I have already created a prototype which fits some of those requirements: we are able to instance a C++ based object, derived from QQuickPaintedItem, which paints its image in the overwritten paint(QPainter *painter) method. In QML, several of these are then instanced and they display their images as I would expect. However, the image content is hard-coded and as these objects are instanced in QML, I'm unsure as to how I would control their contents from my core application in C++. Furthermore, the way we dynamically arrange them is an extremely dirty hack derived from trial and error and works only marginally close to how it is intended: the instances are simply destroyed and recreated whenever the "add one more" button is pressed.
My question is probably a matter of design principle. Even after examining a few examples and further research I am unsure what's the best way to combine the core application and the QML code to achieve what I want.
What is the right approach here? I suspect Models and Views might be the way to go, as I believe I could be able to add the Player components to the model via C++ and therefore have access to them there, while QML would ... somehow ... handle the displaying and arranging.
I'm sorry for the rather vague question, I hope you can help me with a few pointers into the right direction, as to which mechanics I could use to combine QML and C++ for my purposes.
QPaintedItem is unnecessary and will likely constitute performance overhead.
As already mentioned, what you really need to do is implement a QQuickImageProvider which can allow you to do C++ / QML image interop.
Then regardless of whether you need rows, columns or grids, those are all driven by models, you don't necessarily have to implement a C++ mode, QML's ListModel will suffice, as all you really need is a list model of strings, representing the image sources for the custom image provider.
Every time you have a new image coming from C++, you can emit a signal from the C++ side with the image source string, to which you connect a handler on the QML side to add a list item to the model. Expose the emitting object to QML as a context property. As soon as a signal is emitted, the new image source is added to the model and automatically shown in the view. That's pretty much it.

Clojure: how to architect desktop UI

I'm trying to design a desktop UI for schematics, layout, drawing stuff. Just looking for high level advice from actual software designers.
Assuming an in-memory "database", (clojure map of arbitrary depth for all user data, and possibly another one for application preferences, etc.), I'm examining how to do the model-view-controller thing on these, where the data may be rendered and modified by any one or more of:
A standalone text field that shows a single parameter, such as box width.
An "inspector" type of view that shows multiple parameters of a selected object, such as box width, height, color, checkboxes, etc.
A table/spreadsheet type of view that shows multiple parameters of multiple objects, potentially the whole database
A graphical rendering of the whole thing, such as both schematic and layout view.
Modifying any one of these should show up immediately in every other active view, both text and graphical, not after clicking "ok"... so no modal boxes allowed. If for some reason the table view, an inspector view, and a graphical rendering are all in view, dragging the corner of the box graphically should immediately show up in the text, etc.
The platform in question is JavaFX, but I'd like a clean separation between UI and everything else, so I want to avoid binding in the JFX sense, as that ties my design data very tightly to JFX Properties, increases the graininess of the model, and forces me to work outside the standard clojure functions for dealing with data, and/or deal heavily with the whole getValue/setValue world.
I'm still assuming at least some statefulness/mutability, and the use of built-in Clojure functionality such as the ability to add-watch on an atom/var/ref and let the runtime signal dependent functions.
Platform-specific interaction will rest tightly with the actual UI, such as reifying ActionListeners, and dealing with ObservableValues etc., and will attempt to minimize the reliance on things like JavaFX Property for actual application data. I'm not entertaining FRP for this.
I don't mind extending JFX interfaces or making up my own protocols to use application-specific defrecords, but I'd prefer for the application data to remain as straight Clojure data, unsullied by the platform.
The question is how to set this all up, with closest adherence to the immutable model. I see a few options:
Fine-grain: Each parameter value/primitive (ie Long, Double, Boolean, or String) is an atom, and each view which can modify the value "reaches in" as far as it needs to in the database to change the value. This could suck as there could potentially be thousands of individual values (for example points on a hand-drawn curve), and will require lots of (deref...) junk. I believe this is how JFX would want to do this, with giant arrays of Properties at the leaf nodes, etc., which feels bloated. With this approach it doesn't seem much better than just coding it up in Java/C++.
Medium-grain: Each object/record in the database is an atom of a Clojure map. The entire map is replaced when any one of its values changes. Fewer total atoms to deal with, and allows for example long arrays of straight-up numbers for various things. But this gets complicated when some objects in the database require more nesting than others.
Coarse-grain: There is just one atom: the database. Any time anything changes, the entire database is replaced, and every view needs to re-render its particular portion. This feels a bit like using a hammer to swat a fly, and a naive implementation would require everything to re-render all the time. But I still think this is the best trade off, as any primitive has a clear access path from the root node, whether it is accessed on a per-primitive level or per-record level.
I also need the ability for one data template to be instantiated many times. So for example if the user changes a symbol or shape which is used in multiple places, a single edit will apply everywhere. I believe this also requires some type of "pointer"-like behavior. I think I can store a atom to the model, then instantiate as needed, and it can work in any of the above grain models.
Any other approaches? Is trying to do a GUI editor-like tool in a functional language just stupid?
Thanks
I don't think is stupid to use a functional language to do a GUI editor-like tool. But I can't claim to have an answer to your question. Here are some links that might help you in your journey:
Stuart Sierra - Components Just Enough Structure
Chris Granger - Light Table: Explains how Light Table (source) is structured.
Chris Granger - The IDE as a Value: blog post related to the video above
Conal Elliott - Tangible Functional Programming: Using Functional Reactive Programming to create a composable UI, but his code is in Haskell.
Nathan Herzing & Chris Shea - Helping voters with Pedestal, Datomic, Om and core.async
David Nolen - Comparative Literate Programming: Shows all to use core.async to simplify UI programming in ClojureScript. The ideas here can be used in a desktop UI.
Rich Hickey - The Language of the System: Amazing talk about system programming by the creator of Clojure.
Erik Meijer has a good quote about functional vs imperative code:
...no matter whether it's Haskell, C# Java, F#, Scala, Python, PHP think about the idea of having a sea of imperative code that interacts with the outside world and in there have islands of pure code where you write your functions in a pure way.
But you have to decide how big the islands are and how big the sea is. But the answer is never that there are only islands or only sea. A good programmer knows exactly the right balance.

QTableWidget vs QTableView

I am new to this Model/View Framework of Qt. In my application I want to have 1000 X 1000 cells. There should be minimum memory requirement & it should be fast. I don't know what this Model terminology is for. But I have my own class which knows how to deal with the double variables stored in the table. Currently I am using QLineEdit's with a Validator to create the array of cells. But it was way too slow for cells > 50 X 50. So I decided to go the good old MS Excel way.
So which Widget should I use: QTableWidget or QTableView?
And can anybody please explain in short what this Model/View framework is? I am not a Computer Science guy hence I am finding it tough to understand...
cmannett85's recommendation is a good one. Read the docs about a dozen times.
Then, if performance and memory issues are your primary concern and you think you can out-perform the QTableWidget implementation, then a QTableView interface on top of a QAbstractTableModel or QStandardItemModel is what you're looking for.
Since you're new to Qt's model-view architecture, I'd recommend using the QStandardItemModel until you feel like you're getting the hang of it. If your performance still isn't good enough, avoid a lot of the memory duplication and wasted objects by implementing your custom model. Plus, get yourself a good textbook and read its chapter on the model-view framework about 12 times. That section alone was worth its weight in gold, imho.
Here are the basics for Qt's custom model-view framework:
Your actual data is stored in a list/tree somewhere
The model provides a standard framework for queries to and edits for your data
Proxy models allow you to sort/filter your data without affecting the original model
The view provides a means to visually observe and interact with your data
Delegates (often optional) tweak the appearance of your data and provide custom editors to the data
If you're feeling both cheap and brave, check out this excerpt on implementing your own custom model. Work at it one function at a time and play with it as you go.
To understand the framework, start off with the documentation about it. It starts slow, but becomes moderately extensive and covers most of the classes involved.
QTableWidget or QTableView?
Once you have read the documentation you will see why this question doesn't really make any sense: a QTableWidget uses a QTableView to display the data. QTableWidget (along with QTreeWidget, etc.) uses the MVC framework, but it encapsulates it all to a handy package useful for most purposes, but if you need to do something different, you will have to crack it into it's component parts and reimplement the bits you need.

Node graph editor layout algorithm

I'm very much trying to do what was asked here:
http://www.qtcentre.org/threads/45028-Designing-a-Node-Editor-(Hint-Blender-Node-Editor)
Which is basically a blender style node editor using Qt. Creating rects with circles which can be drag/dropped is fairly simple to figure out (see the image below).
The issue I have is how the algorithm for connecting the circles between nodes would work. Also I don't know how this could be drawn efficiently using QGraphicsItem API's? I have seen QPainter::cubicTo() which looks like it may be the way to go?
I assume it somehow manages to find a none overlapping path? But it must also handle the case where it has to overlap?
And what about the user being able to move these lines around in case the algorithm has done a bad job? I don't think this would be simple to implement using QPainter::cubicTo() as you could only move the curves control points?
I don't think you'll get anyone posting the code for doing the whole lot here.
Well, I volunteer -- just in case someone still needs such a library.
It is a Qt-based node editor implemented on top of QGraphicsView.
A library consumer defines data models, the rest is done by the node editor.
Some features:
Model-view approach.
Models describe data types, number of input and outputs and optional embedded QWidget.
The Scene could be saved to file.
The rest similar projects were either not finished, not supported anymore or lacking some features.
https://github.com/paceholder/nodeeditor
I would suggest that you implement it without taking into consideration overlap but with the possibility of overriding how the connecting line is drawn.
It looks like there were some good replies on the Qt forum. I don't think you'll get anyone posting the code for doing the whole lot here.
Perhaps take a look at the Qt demos Graphics View/Elastic Nodes - There is code for the demo that you can use as a starting point, but it is a lot of work to get from there to something like the Blender node editor.
Another node editor to take a look at is SynthEdit or Synth Maker (has a nice one).