Both can create objects dynamically.
When should Loader be preferred over Qt.createQmlObject and vice versa in QML?
The Loader can be regarded as a placeholder for a particular object. It also gives you the ability to reference the underlying object through the Loader's id.
Qt.createQmlObject is generally more powerful than a Loader, because you can instantiate as many objects as you want, and also it doesn't have the overhead of the Loader. But you have to take care to keep track of what you create in order to be able to reference it.
The other functions Qt.createComponent() and then createObject() offer similar advantages, plus the possibility to pass properties to be used in the object's creation instead of setting them only after it has been created.
I personally see very little point in Loader and rarely use it, if at all in production code. IMO it was introduced for the sake of the "non-programmer" much like most of the recent development, such as the new designer and QML .ui files, which I find kind of annoying, but it is understandable - trying to increase adoption by non-programmers.
Related
I am trying to develop an application with Qt 5.5 and OpenGL. The basic work of the application will be to load simple objects, modify their positions in a scene and save them together with other attributes (material, name, parents/child relations etc...).
The only thing I am struggling about for a week now is that I really don't know how I should take on the problem of synchronizing data. Let's say I have some kind of SceneGraph class which takes care of all SceneObjects. Those SceneGraphs should be rendered in a SceneView-Widget which can be used to modify it's Objects via transformations. Now how would I tell every SceneView that an Object changed it's position?
I thought of the Model/View architecture for a moment but I am not really sure how this implementation should look like.
What would be the best way to handle Objects like that in different Windows/Widgets but still have one single piece of data?
SceneObject:
Holds the mesh-information (verticies, uvs, etc..)
Has a name (QString)
Has a material
Has a transform storing position, rotation and scaling information
(Important: these datatypes should be synchronized in all views)
SceneGraph:
Contains different SceneObjects and is passed to SceneViews
SceneView:
The QWidget responsible for drawing the Scene correctly in any QWindow.
Has it's own camera to move around.
Handles UserInput and allows transformation of SceneObjects.
You could use the signal and slot to observe position updates of SceneObjects and process them in SceneView.
I have a program consisting of multiple SWF's. An AS2-SWF loads a bunch of AS1-SWFs.
It's a crappy program. I'd like to specify the GUI in MXML and perhaps refactor some code to AS3. However, converting all of the 300+ symbols to AS3 or whatever is undoable.
What are my options in converting to AS3/Flex/MXML? The app is very simple, only also quite large. It consists only of buttons, backgrounds and attention-texts. All the button texts are in XML files.
I want to turn this into pretty code ASAP but also controlled so the code becomes:
easily updateable/maintainable,
readable
learnable (so I can have the updating done by someone that can only script AS3 or even MXML).
Of course doing this is on my own initiative, if it'll take more than a week, I won't be able to find the time.
Regards, Jurgen
This might help:
http://flexman.info/2009/03/29/as3converter-an-ant-task-small-collection-of-as3/
It's mainly for AS2 code, so FLA editing is out of the question. But you should certainly look into JSFL.
There are some pretty good scripts out there already dealing with something like this:
http://bumpslide.com/blog/2009/03/07/jsfl-class-generator/
What this command does is that it
looks through your library and finds
all library items that have a custom
linkage class name. If the class
extends flash.display.MovieClip (or if
the base class is blank), it checks to
see if a classfile exists, and if not,
it creates it for you. When it does
this, the script looks at all the
items on the timeline and adds
relevant properties to your class. If
these clips are instances of other
components, they will be typed as
such, and relevant import statements
will automatically be added to your
class. If your component is set to
extend some other class (for instance,
com.bumpslide.ui.Button), no class
will be generated. Class files will be
written to the correct package
location inside the first custom class
path defined in your publish settings.
Jurgen, I feel for you... it sounds like a lot of work.
What sorts of issues do you have? are all the swfs treatable as different classes? is there much overlap in the logic or does each object have a specific role?
I think having so many different SWFs may possibly lead to scoping problems> which swf talks to which. you may be able to set up something with as3 that uses the existing parts and then try making a facade over the existing code > use the existing logic in the swfs and do the visual part through mxml. other than that, all I can advise is a rebuild. you might find yourself in need of a swf decompiler too if you are missing some of the original fla's
I've got a person object with a name and age property that implements INotifyPropertyChanged. I want to hook this object up to an ASP.NET form so that the 'name' and 'age' properties bind to textboxes in a way that, when changes happen in either place (in the control or in the object) the other will get updated.
Do I create an intermediary class that listens to each textbox change events and the objects change events and handle the updates between them? What's the best way to do this?
I'm unclear on how to get business objects and the UI talking to each other.
I've stressed over this exact problem a lot.
The short answer is, yes, an intermediate item.
The trick is to NOT write ANY code per control. You should be able to place a GUI control on the screen (That may or may not take code), and then bind your business logic to it through a generic binding mechanism.
I have defined the bindings through XML, through properties files, and through constant arrays--there are a million ways...
You probably have to write code per TYPE of object bound (a listbox binds differently than a text control) and you may have to write validators (but specifying the parameters to the validators and which control the validators bind to should also be done in data)
Now all that said, I'd be really surprised if some data-driven auto-binding mechanism didn't already exist, Microsoft has been into that since VB first came out (although their implementations used to be pretty inflexible, I'm sure they do a better job now).
I'm very insistent about the 0 lines of code per control because my job has typically involved configuring complex devices with dozens of pages of controls. A typical client/server system will have 7(!) lines of code PER CONTROL just to transport data from the DB, to the server, to the client, to the screen and back (this is a minimum for plain ole "dumb" code with no smart binding tricks).
0LOC/control may not be a requirement for everyone, but it's a good goal.
Comment response:
I've done most of my stuff manually in Java, so I'm not sure I can be too much help with the specifics.
Searching for C# and binding gave me this which looks promising, although it may be binding straight to a database which is too much IMO, it should bind to a business object, but the concepts should be the same.
One way to create the bindings at first is to manually instantiate binding objects... (Please excuse my Java)
TextControl textCtrl1=new TextControl("Name Goes Here");
new TextBinder(textCtrl1, personObject, nameField);
In Java, that second line gets tricky. When you are binding to a particular field, you HAVE to use reflection to find the setter and getter for that field of the personObject. In C# I think it should be easier.
Anyway, the binder should add itself as a listener to the control and the object, then forward changes back and forth.
Does that help any?
Edit2:
As you noticed, the hard part is noticing when your property is updated. Luckily, that is optional. More often than not, you don't need to update the component once the object is set (I had to deal with this a few times when I had distributed UIs that could update each other).
So, if you assume your object won't change, the "Binding" has to do the following:
get the value from the property and set it in the component.
add itself as a listener to the component.
store the property/object (if you can manipulate properties, you're set here. If not, you need to store the object and property name, and use reflection)
bail and wait for an "updated" event from your component.
When you get the update from your component:
- store the value in the property.
- You may want to set an "Updated" flag or store the original so that if you iterate through all the binding components, you can tell if any updates need to be saved/enable the "ok" button.
Your object should always be pretty much up-to-date now.
As you build a form, you may want to put all your binding controls into a collection so that you can do a few other operations...
A "Save" operation could call each binding control and tell it to copy from the control to the property, that way you don't need to use a listener.
A "Reset" operation can reset all the controls to their original value.
A "Test" operation can ask each control if it's been updated.
. etc
The neat thing about doing it this way is that every "Operation" you wish to add is pretty trivial to add, but automatically affects the entire UI.
You probably also want a little object hierarchy of controls with an abstract base "bind" class, then a specific binder for each type of control (text field, number field, date, spinner, table, pulldown)--I think that's about it.
This can be very simple, but gains complexity rapidly. Try it with a text field and see what you can do. A simple text binding object should just be like 5 lines of code if you can pass "properties" around in C#...
Okay, totally separate answer. As I told you, I'm not very up-to-date with C# technologies, but from what I've heard, LINQ may do this entire job for you.
In fact, LINQ may be made to do exactly what you are trying to do. It doesn't exist in Java, so that's why I gave you the "Manual" version in the other answer.
The comment at the bottom of this page: http://msdn.microsoft.com/en-us/library/z919e8tw.aspx alludes to a better way.
Meaning . . . I've seen cases where I've bound components to a [Bindable] dataProvider. When I updated the data in the dataProvider, the component doesn't reflect the change immediately. Do I need to do something to refresh the data? What event causes a component to refresh its dataProvider data?
This is probably overkill, but if you are really interested in what happens under the hood when you add the [Bindable] tag, I strongly recommend checking out Michael Labriola's Diving in the Data Binding Waters session from 360|Flex!San Jose. It is by far the most in-depth presentation on this subject that you will find.
To view it you'll need to download Adobe Media Player (which runs on Adobe Air). If you have problems subscribing to the 360|Flex sessions in the Adobe Media Player, follow Ted Patrick's advice from Deleted link his blog post.
His presentation is also on Slideshare, but it's nowhere near as informative or entertaining.
Chapter 7 of the developer's guide deals exactly with this. I suggest you read it.
Excerpt:
Although raw data objects, such as an
Array of strings or objects, are
wrapped in collections when you use
them as the value of a dataProvider
property, using collections explicitly
is a better practice. Using
collections explicitly ensures data
synchronization and provides both
simpler and more sophisticated data
access and manipulation tools than are
available when you are using raw
objects directly as data providers.
Collections can also provide a
consistent interface for accessing and
managing data of different types.
See also this about data binding and arrays
that would depend on what you did to the data.
did you apply a filter, if so you'll need to refresh the data.
did you do a sort, if so you'll need to refresh the data.
Is your dataProvider an Array, if so this doesn't do binding, use an ArrayCollection.
Give us an example of what it is that isn't updating and we should be able to give specifc help.
If you're into fiddling around with the command line compiler, you can use the compile.keep-generated-actionscript flag to see the effect of adding [Bindable] to a property. Create a simple actionscript class called test and add a single bindable string property to it then compile it like this :
mxmlc -compiler.keep-generated-actionscript test.as
This will create a folder called "generated" containing all the extra action script, which in this case would be a single file called (probably) "_test-binding-generated.as".
You should be able to see from this that adding the bindable tag just creates a wrapper which implements IEventDispatcher and dispatches an event when the setter is called. It's this wrapper that your component will be listening to.
If your component isn't immediately reflecting the change in its display, this might mean you'll have to look into the redraw code of that component. The Tree control is pretty notorious for this kind of issue, mostly because updating can be expensive.
"When a property is the source of a data binding expression, Flex automatically copies the value of the source property to any destination property when the source property changes. To signal to Flex to perform the copy, you must use the [Bindable] metadata tag to register the property with Flex, and the source property must dispatch an event."
Ok, so I know that global variables are considered bad, and the singleton pattern is overused. And I have read in many places that a class should do only one task and contain only those variables that allow it to accomplish that one task. However, while working on my latest project, I actually thought about these rules before writing any code and have noticed that I tend to break them at the very beginning of the program.
I'm currently working on an MFC dialog based application, but this question could be applied to any UI driven application. I have separate classes that handle state machines, file reading/writing, and hardware interfacing. All of these objects will need some type of UI control or property display/editing. In the MFC dialog applications, the dialog is the program, so it must exist until the program is closed. I've usually just put the objects in the main dialog class for the application and had the dialog class serve double duty; as both the main UI and the home for all other objects in the application. In other applications, I've created these objects globally and referenced them from wherever they were needed. Neither of these ways seem correct. The first option breaks the one class, one task rule, and the second relies on globals and also creates hidden dependencies. I could institute some type of dependency injection, but where would all these variables that I would inject reside?
I'm just wondering what others do to organize their programs without breaking the rules?
I find that storing singletons as public data attributes of the main dialog class of an MFC dialog application works OK for a quick and dirty program. However, as the program becomes larger and more complex, things begin to get untidy.
The point where storing singletons in the dialog class needs to be refactored is probably when you start passing pointers to the dialog around, so that other classes can access the singletons it contains.
The singletons can be moved into the global namespace. This is still a bit untidy, especially when there are a large number of them. Since you have to write a separate extern for each one in a header file then define each one somewhere, you soon end up with something that looks a lot like an old fashioned C program.
A neat thing to do is to make use of the singleton that the framework has already defined for you.- the application object which is always called theApp, a specialization of CWinApp. If you place your singletons as public data members of this, then any code can get easily get access to them .
Suppose that you called your application “solver”. The dialog application creation wizard will create a class CsolverApp. Now suppose you have a singleton called ‘theData’ an instance of the class ‘cData’.
Place your singleton in the theApp
class CsolverApp : public CWinApp
{
public:
cData theData;
…
Now to access this from anywhere in your code
#include “solver.h”
theApp.theData.somepublicmethod();
It does make sense to look at this from the MVC (Model - View - Controller) viewpoint. (That the naming of MFC is an homage to MVC is another sick joke on Microsoft's part; it is hard and unintuitive (but by no means impossible) to manage the types of abstractions that are necessary in "true" MVC within MFC.)
Specifically, it sounds like you've thought out the basis for MVC design; you have the classes that do the underlying business logic work (the Model), and you know they should be separated from the UI components (the View). The issue that comes in now is the third part of the MVC trinity; the Controller.
MFC makes this stuff tough by apparently purposefully obfuscating the MVC process, by making you start with a Dialog. In your instance, the Dialog that MFC is starting you off with should be the Controller, and NOT the View. What your Dialog (Controller) is doing for you is managing your UI components (View) and allowing them to interact with your "work" classes (Model). What makes this tough again is that your UI components, to be visible, most likely need to be attached to your Dialog to be visible.
To get this sort of thing right, you really have to basically implement your Controller as a high-level object that gets instantiated from your Dialog; your Dialog is where the initial control flow comes in, your Controller gets control flow, and from there, it should treat the Dialog as just another UI component (albeit one with special status).
This allows you to have the proper level of encapsulation; your Controller invokes your business logic (Model) classes, which can communicate with each other or with the Controller as appropriate; they are segregated from the View by the Controller, instead of being embedded in the UI components and (likely) taking the "easy way" of over-privileged access to UI elements ("Hmm, I need this object to get some input from the user; I could refactor, but it'll be so much easier to just throw a dialog box up, since I have the top-level window handle...").
Once your Controller object is the home to all of the business logic objects, things become easier; you can use the Controller to provide cross-object access for any objects that need other objects. Think about which classes need to be Singletons, and use them sparingly. Resources that need contention management (such as hardware resources) are great examples of "natural singletons"; things which lend themselves to a singleton approach. You may also choose to make your Controller a singleton; depending on the requirements for access to it. Specifically, in your Dependency Injection scenario, the Controller is where you'd instantiate the objects and manage the dependencies.
This is the basic MVC approach; but, like I say, MFC makes it unusually hard and unintuitive, because of the fundamental design of MFC. I learned MUCH more about MVC AFTER an initial VERY negative impression about it due to MFC; if you can, I recommend looking into what MVC implementations look like in other languages.
Good luck!
If I am understanding you correctly, it sounds like the lifetime of your dialog objects is too long. Rather than maintaining the dialogs for the duration of your program, you should consider creating and destroying them as they are needed.
Also, global variables (or singletons) are OK so long as the thing that the variable represents is truly a global thing that persists for the lifetime of the program, rather than just a place-holder for an object of lesser duration. Using globals for the wrong things for simplicity sake will come back to bite you eventually, even if the globals are stored on the main dialog.