I would like to develop relatively simple dialog-based GUIs for Raspberry PI 2 (Linux/Raspbian) that is why would like to study Qt beginning with the basic/core features. RTFM, I know. So I read one of them, and to be honest understood very little.
The biggest question in my head: Why would it have been worth reading in the first place? What is the purpose of the Qt properties? What are they good for?
How do they work internally and from the point of view of writing the code.
What is the memory and performance cost? Is it necessary to use them? If not, is it worth using them considering my use case?
Properties are used to read/write values in objects through a standard generic interface. Needed for interfacing with script engines (QtScript or QtQml), the widget designer, remote object interfaces (QtDBus, QtRemoteObjects, QtWebChannel).
Most properties get implemented through normal getter/setter functions which are then tied to a property name and registered with the property system using the Q_PROPERTY macro. Alternatively the property name can be bound to a member variable. Read/write access with the generic property() and setProperty() API is the rerouted either to calls to the registered getter/setter or to the registered member variable.
The property information is stored as a QMetaProperty in the class' staticMetaObject, access through the property API will incur a lookup based on the property name.
Your use case doesn't seem to require usage of properties.
Another use case, as mentioned by Kuba in the comment, is to attach data to QObject based objects without modifying them.
These kind of properties, so called "dynamic properties", are handled slightly differently. Instead of getter/setter functions or a member variable, they are stored in a generic internal storage, currently a QVector<QVariant>
Related
In relation to this topic: What is the copy-and-swap idiom?
It states that one class should at most handle one resource. What is meant by resource?
EDIT: For example I have a class that handles the information for each monitor, and contains an array of the desktop pixels. Would the array and only the array be considered a resource? Would the array of monitors that hold the monitor information and array of the desktop pixels another resource, that would require another class? It is in another class, but is that what is meant?
I have searched here and Google but only find more information relating to the rule of three or resource files (*.rc and MSDN). Nothing that relates to a definition.
That question is referring to concepts in C++ in general. In this case, it is also using the general concept of a "resource": an object, usually external, provided by an outside source, that a block of code uses. It's the same as a "resource" in real life.
In the case of copy-and-swap, it is referring to what your C++ class represents. The idea is simple: each instance of your C++ class will provide access to a given resource. For instance, let's take a file on disk. The resource is the file; the operating system provides access to that file. Your C++ class would wrap around the operating system's API calls to read and write to that file.
The question that you linked is asking about how to mix these classes with C++'s initialization rules. How you follow these rules is going to be shaped by what accesses the outside source lets you use and what you personally need to do.
Of course, your program can also have its own resources. For example, a global array that maps one type of enumeration to another type of enumeration could be a resource in your program. So the answer to your question of "what should be a resource in my program" is "it really depends on how you wrote your program".
Windows programs also have their own "resources", such as bitmaps, icons, dialog box control layouts, menu layouts, localized strings, and other stuff. To allow these things to be embedded in the output binary, Windows provides its own system, and also calls all these "resources". A .rc file is merely how you would list all of these Windows resources; you build that into your Windows program.
GLib (which GTK+ is built on top of), Qt, and the various Apple APIs have their own analogous systems, each of which also have "resource" in their names.
(You can write C++ classes that provide access to all these specific resources too; in this case, the resource is the resource.)
But it is very important when reading not to confuse he general term ("resource") for the specific technology (Windows resources) and vice versa, especially for such an abstract concept as a resource. Keep that in mind as you continue your programming journey.
Resources, are things like: raw pointers that need to be deleted (that's why we have smart pointers like std::unique_ptr, std::shared_ptr), files that need to be properly closed (that's why we have std::fstream), std::thread (to manage the raw handles that you would have to otherwise manage yourself in different operating systems). std::reference_wrapper manages references... and so on. As you may have noticed all of them manage a single resource, not more.
The idea is that you don't want a single unique_ptr to manage 2 pointers for you. You would create two unique_ptr classes for each raw pointer.
For your specific question which you have edited, generally what you wanna do is:
create a class MonitorsManager that manages all the monitors (that's his task)
create a class MonitorInfo (that manages a single monitor information and the pixels
You will notice things get easier if you have a good design, because in the future you will want to be able to easily edit and update those classes, and if you mix everything, it's gonna be really hard, trust me.
Also, your MonitorInfo class should not have any dependency on MonitorsManager because if people has to include the class "MonitorsManager" in their project in order to use your "MonitorInfo" class, then you have failed. Not everyone has multiple monitors, some may have a single one.
For example, an empty QObject-based class defined in C++. It's created from QML. Then C++ adds some properties to it via setProperty. But they aren't becoming accessible by QML.
Other example: use setContextObject and then start adding properties to that C++ object. No effect on QML.
How to make it work?
update
I see two options: private API (MetaObject builder) and code generation for QML items at runtime.
I think you're looking for QQmlPropertyMap. It allows you to add properties dynamically. It's usually better to predefine values through qt models in C++ though, and there aren't many good use cases for using QQmlPropertyMap.
There actually several ways to do this, this article has a great explanations.
The DYNAMIC FACTORY pattern describes how to create a factory that
allows the creation of unanticipated products derived from the same
abstraction by storing the information about their concrete type in
external metadata
from : http://www.wirfs-brock.com/PDFs/TheDynamicFactoryPattern.pdf
The PDF says:
Configurability
. We can change the behavior of an application by just changing its configuration
information. This can be done without the need to change any source code (just change the descriptive information about the type in the metadata repository) or to restart the application (if caching is not used – if caching is used the cache will need to be flushed).
It is not possible to introduce new types to a running C++ program without modifying source code. At the very least, you'd need to write a shared library containing a factory to generate instances of the new type: but doing so is expressly rules out by the PDF:
Extensibility / Evolvability
. New product types should be easily
added without requiring neither a
new factory class nor modifying
any existing one.
This is not practical in C++.
Still, the functionality can be achieved by using metadata to guide some code writing function, then invoking the compiler (whether as a subprocess or a library) to create a shared library. This is pretty much what the languages mentioned in the PDF are doing when they use reflection and metadata to ask the virtual machine to create new class instances: it's just more normal in those language environments to need bits of the compiler/interpreter hanging around in memory, so it doesn't seem such a big step.
Yes...
Look at the Factories classes in the Qtilities Qt library.
#TonyD regarding
We can change the behavior of an application by just changing its configuration information.
It is 100% possible if you interpret the sentence in another way. What I read and understand is you change a configuration file (xml in the doc) that gets loaded to change the behaviour of the application. So perhaps your application has 2 loggers, one to file and one to a GUI. So the config file can be edited to choose one or both to be used. Thus no change of the application but the behaviour is changed. The requirement is that anything that you can configure in the file is available in the code, so to say log using network will not work since it is not implemented.
New product types should be easily added without requiring neither a new factory class nor modifying any existing one.
Yes that sounds a bit impossible. I will accept the ability to add ones without having to change the original application. Thus one should be able to add using plugins or another method and leave the application/factory/existing classes in tact and unchanged.
All of the above is supported by the example provided. Although Qtilities is a Qt library, the factories are not Qt specific.
I'm writing an NPAPI plugin in C++ on Windows. When my plugin's instantiated, I want to pass it some private data from my main application (specifically, I want to pass it a pointer to a C++ object). There doesn't seem to be a mechanism to do this. Am I missing something? I can't simply create my object in the plugin instance, since it's meant to exist outside of the scope of the plugin instance and persists even when the plugin instance is destroyed.
Edit:
I'm using an embedded plugin in C++ via CEF. This means that my code is essentially the browser and the plugin. Obviously, this isn't the way standard NPAPI plugins behave, so this is probably not something that's supported by NPAPI itself.
You can't pass a C++ object to javascript; what you can do is pass an NPObject that is also a C++ object and exposes things through the NPRuntime interface.
See http://npapi.com/tutorial3 for more information.
You may also want to look at the FireBreath framework, which greatly simplifies things like this.
Edit: it seems I misunderstood your question. What you want is to be able to store data linked to a plugin instance. What you need is the NPP that is given to you when your plugin is created; the NPP has two members, ndata (netscape data) and pdata (plugin data). The pdata pointer is yours to control -- you can set it to point to any arbitrary value that you want, and then cast it back to the real type whenever you want to use it. Be sure to cast it back and delete it on NPP_Destroy, of course. I usually create a struct to keep a few pieces of information in it. FireBreath uses this and sends all plugin calls into a Plugin object instance so that you can act as though it were a normal object.
Relevant code example from FireBreath:
https://github.com/firebreath/FireBreath/blob/master/src/NpapiCore/NpapiPluginModule_NPP.cpp#L145
Pay particular attention to NPP_New and NPP_Destroy; also pay particular attention to how the pdata member of the NPP is used.
This is also discussed in http://npapi.com/tutorial2
There is no way to do this via NPAPI, since the concept doesn't make sense in NPAPI terms. Even if you hack something up that passes a raw pointer around, that assumes everything is running in one process, so if CEF switches to the multi-process approach Chromium is designed around, the hack would break.
You would be better off pretending they are different processes, and using some non-NPAPI method of sharing what you need to between the main application and the plugin.
I've often come across APIs that allow users to get and set various parameters that control a module's operation. I now find myself contemplating writing yet another properties API but don't want to reinvent the wheel.
The following is typical basic client code:
setInt("bitrate", 1000);
setEnum("mode", MODE_FAST);
setStr("output file", "music.mp3");
Frequently there are dozens of parameters that can be set and such property sets are often under continuous development.
Some APIs are smarter than others, more advanced features being:
Hierarchical grouping of properties
Enumeration of properties
Numeric parameters with enforced minima and maxima
Default parameter values
Settings that are enabled, disabled or read only
Dynamic parameters - settings that appear, disappear, have min/max set, become enabled, disabled or read only depending on other parameters' state.
Properties accessed via UUID key rather than textual name
Beyond the C-style accessors in the sample code above, I've come across frameworks that can:
Read/write properties to file (e.g. XML)
Read/write settings to Windows Registry
Interface with system properties APIs like IPersistPropertyBag
Have default dumb GUI implementations, e.g. tree-view or list
Have GUI extensions appropriate to minima/maxima/enabled state reducing repetition in GUI code.
I would love to find a well-designed public library that provides a framework for all of the above but so far have drawn a blank. I'm aware of Boost.PropertyTree but it's only really a skeleton. Are there other portable properties API frameworks that I should be aware of?
One of the key elements of the Qt property system is actually a very solid implementation of a variant type class QVariant that enables you to get rid of the typed setInt, setString ... calls.
If you get a hold of a similar well behaved class e.g. possibly Boost::Variant or something similar a property system is fairly easy to implement using a map of string as the backing part.
One of the conveniences of the qt property system is that you can override setter and getter functions without the user having to know about them. E.g. given your generic property setter being setProperty(name, value). The implementor can in the class declaration denote that the property "speed" has its own setter setSpeed(float value) so that when a user of your class invokes the generic version of setProperty("speed", 100), the system will call setSpeed(100) on your instance.
If you don't need features like that you can probably implement your own property system. Gamasutra has a piece on implementing reflection in C++ that might help you too.
If you don't mind having a dependency on Qt Core, then Qt has a fairly well designed property system. This means though that you will be relying on Qt's MOC.