I am building a QtQuick app, and i need a TCPSocket that polls a device and fills the data structures I want to show. I've found a lot of samples about sockets and Qt 5 widgets, but i'm not able to create the socket as a C++ class that's not derived from QObject.
My understanding is that I only need to derive from QObject if I want to exchange data with my QML view. I wrote an additional class that does that, so my socket class doesn't have a need to pass any data to my QML code.
The question almost doesn't seem to be a Qt question, but a C++ network programming question. I gather that you basically dislike explicitly using custom QObject-derived classes since you don't want to run moc as a part of your build process. While one might argue what's so bad about it, since moc is run a whole lot during the building of Qt proper, let's go with what's asked for the moment.
If you're looking for non-Qt-based pure-C++ networking, then Boost ASIO is a very solid solution.
If you wish to use Qt networking without a custom QObject-derived class, then you can run the code in a separate thread and only use blocking QTCPSocket calls. After all, it's a QIODevice and offers blocking interface.
Eventually, you end up with some data structure that's filled and should be passed on to QML.
Logically your data is a data model, and the view is in the QML code. You can use QStandardItemModel for that - that is, if you are writing true model-view code, like you would if the data will change over time. Again, you're re-using an existing QObject-derived class, without deriving your own, without writing any custom signals nor slots.
A really poor-man's workaround is to take a naked QObject and put data in it using the dynamic property system via QObject::setProperty. I don't recall offhand if dynamic property changes are seen via the QML engine, you'd need to verify that or simply treat such objects as constants.
All of this seems to be a lot of workarounds for a rather silly reservation. Code generators are good, they save time. The build process of a complex C++-based product may use several different code generators, such as lexer/parser generators, state machine generators, remote procedure call generators, table generators, test case generators, etc. As C++ matures, ways are found to coax the compiler to replace some of those generators, but that's merely pushing the problem to a different executable, and sometimes pushing it through a very small needle hole as well.
Related
I recently read an OOP book (Robert Martin I think) that emphasized using a core object that calls interfaces of the things it uses. The point here is that the peripheral objects depend on the core rather than the other way around. This allows better modularity, flexibility, distribution of binaries, build time, etc. Supposedly you can also allow your program to be independent of any particular framework, eg GUI, database, etc. But I'm having a hard time separating the framework from the core.
For example the Qt framework provides class QTreeView; some functions take instances of QAbstractItemModel.
It's conceivable I find or write a different model/view I want to use that is not part of the Qt world, or use some immediate-mode api for the graphics part, etc.
So how do I write my core to be agnostic of Qt entirely?
Do I make up an ITreeView with similar functions as QTreeView, with similar-sounding non-Qt arguments and then delegate to a real QTreeView instance after converting all arguments to real Qt types? It seems silly to recreate so much of the framework just to make it generic.
Or in the real world are people fully absorbed into Qt and it's not realistic to keep it separated?
I'm developing a C++ app using Qt. The app displays some various customized widgets that are made using QML. These widgets renders values using signal/slot system.
I was wondering what could be the best way to manage:
Manage everything in qml files, including rendering and business rules.
Embedding qml files into QWidget class (QQuickWidget) and managing rendering and business rules in c++
When you want to get things up and running fast doing the buisness logic in QML is a good way to go. But things will getting complicated when adding new features. After a while we got a lot of cascade-like callbacks by depending signals-slots in your QML-files. Special when mixing view- and buisness-code in one QML-file will make your code hard to maintain.
To avoid this using some kind of MVC or MVVM-pattern to separate buisness-logic from your view-code makes sence. And of course you can do the buissness-logic in QML. Separation of concerns helps a lot to keep your code-base understandable independent from your programming language.
When you have any performance-concerns regarding your buisness-logic using C++ for it is the best way to go ( made these experiences when starting with a first prototype in QML and needed to port it to an embedded platform ). And you can use C++ for some special QML-Elements as well of course.
So it strongly depends on your problem.
Depends on how complex your core logic is. If it is small and simple, do in QML. Even if it is not that small and simple, there can be quite a lot of benefits to using QML, as prototyping there is much, much faster and easier compared to C++. You don't have to recompile, you don't get crashes but fairly useful error messages. I find QML to be 5 to 10 times faster for prototyping than C++.
You can always move things over to C++ if you want better performance or memory efficiency, and it is a seamless plug and play transition, because you can use signals and slots in both worlds. It is usually faster to develop the algorithms in QML and port to C++ than to do in C++ from scratch. The downside is you have a different toolset on the low level, in C++ you can use Qt's core classes whereas in QML you will have to use JavaScript and its programming idioms. It really depends on how much experience you have with both, but with some practice, it is quite easy to translate QML to C++.
That being said, even if you opt for QML for the logic, it is always a good idea to have it as a separate layer from the GUI.
Unless you need QWidgets for something else, there is absolutely no good reason to use QQuickWidget, thus you can avoid the entire widgets module as a dependency. You do not need widgets to do the core logic in C++.
I have the following question regards qml object loaded with qml Loader (setSource("qmlObject.qml")).
In qmlObject.qml I have imported objectClass(.h/.cpp) created with qmlRegisterType, thus when I launch loader.setSource("qmlObject.qml") command an instance of objectClass(.h/.cpp) is created.
I have other main class named coreClass(.h/.cpp) and I should exchange data between objectClass(.h/.cpp) and coreClass(.h/.cpp).
What's the best practice to implement this feature in my simple qt application?
There are two ways to do that:
on C++ level, since both your objects are C++ objects, you can skip using QML as an intermediator and communicate directly. Presumably your core class will be one for the whole application, so you can expose it as a static member pointer to the core in your object class. Therefore all object class instances will have access to it.
on QML level, by exposing the core class to QML as a context property, or preferably as a singleton, because the latter is the most efficient way. Then you can use its properties, signals and slots (but not pure public C++ stuff) in the form of a defined functional interface.
The first approach will be much faster performance wise, and will use less memory, the downside is you will have to recompile the C++ code on every change.
The second approach will limit the interaction to what is visible in QML, which is properties, signals, slots, and functions that have been marked as invokable. It will be slower and use more memory, but on the upside you won't have to recompile, so prototyping is much more rapid.
Often such interactions will be GUI based, so the overhead will not really matter, as the user doesn't interact with the GUI thousands of times per second. If efficiency is key, you can prototype using the second approach and get things running faster, and when you are done simply port the code to the first solution.
It is also important to mention that when you do C++ to QML integration, the correct way would be to have the C++ stuff exposed to QML and use it from QML. You should never ever have to reach from C++ to arbitrary stuff in QML, this is an indication of wrong design.
You can easily exchange data between c++ classes with SIGNAL and SLOT mechanism.
just pass pointer of coreClass to objectClass and connect signal and slots.
Background
I need to implement a dynamically-configurable data-processing toolkit. There will be several data processing entities, which can be combined to a data-flow graph by using a GUI tool.
The idea is similiar to Direct Show filter graphs (GraphEdit) or Apple's Quartz Composer.
The GUI tool will store graph definitions in a file. When the actual processing is started, this definition file will be read, and data processing objects have to be created and connected at runtime.
I have used Qt's signals and slots for similiar problems before, but this time the main program does not have any GUI. So I'd like to use something less bloated.
Question
What is the easiest way to have signal/slot functionality with basic reflection, without using Qt?
I need to define a fixed number of slot types (each with a certain predefined function signature).
For example, there will be an image-consuming slot, taking an image object as parameter, or a slot just taking an int as parameter.
At runtime, I need to iterate through all signals/slots and connect them dynamically.
I do not need to inspect Slot/Signal Parameters at runtime. It sufficient to have a fixed number of parameter sets. It would be ok to put some kind of hint in the slot's name to identify the signature type.
I know that boost ships with signal2, which provides signal/slot functionality. But whats the fastest way to implement reflection? Should I build my own set of macro-hacks?
I haven't used it, but it seems cpgf has all features you need (reflection and signal/slot).
I believe you can use Qt to develop non-GUI tool. AFAIR, doxygen uses Qt. But I didn't use Qt by myself yet.
Also a suggestion is that you should NOT implement you reflection system unless you are ready to invest a lot of your time and energy. You may implement a dirty and quick reflection system in your app but then you may find you need more time to maintain or improve it as your app growing.
Also forget macros for reflection. Macros are too ugly and too error prone.
For my cpgf library (I'm the author), I'm not ready to promote it yet because it's quite new (less than one year) and not as mature as other library. However, I really appreciate if any real projects use it to verify it works in real world than just works in unit tests. And I would like to give necessary assistance to the projects for bug fixing or something like that.
Boost also has an implementation of signal and slots
http://www.boost.org/doc/libs/1_49_0/doc/html/signals.html
Does it make sense to use Qt for increasing the productivity in an MFC app, without actually using the Qt user interface system?
I am currently looking or a good productivity library for my MFC based application, with useful container classes, string algorithmus, threading classes, I/O classes and so on. The Qt API is very nice in my opinion. However, since I don't want to switch my UI to Qt (just too much effort), I am wondering whether Qt can be used well in a MFC app without any Qt UI.
Thanks in advance for your opinions.
Fabian
Qt is divided into several modules (QtGui being one of them). You can hand pick which modules are used by your application by linking only against the libraries you need.
I cannot answer whether Qt will be interopable with MFC. But at the very least, QString offers conversion to std::string and char*/wchar, which should help you quite a bit.
The Qt documentation provides an overview over the modules.
As daniel pointed out below, you have to be aware of the event loop. It is possible however to use the event loop without the GUI module. You can call processEvents on QCoreApplication to process all queued events and then return. There is one caveat with deferred deletions, but the documentation describes the workaround.
There are some utility classes that you can use but there is a very important caveat. Qt depends very heavily on its event loop. The event loop is started by calling QApplication::exec(). Now many Qt classes depend on the signals and slots mechanism is Qt. Signals and slots are totally dependent on the event loop to function correctly.
This is totally true for the GUI modules but is also true of some of the other modules. One can expect every class derived from QObject to use signals and slots and will therefore be unusable without the event loop.
Sure, you can use QT toolkit without using it's GUI library.
Depending on your needs, you might want to consider boost libraries which provides a sane set of APIs that helps for many things. I personally use it for doing network sockets in a multi-platform way, but there is a lot more in it.
yes you can, you have just to exclude QtGui Module from your project (.pro) because it included by default.
QT -= gui
like this the Core Module only is used.
The Mumble project uses Qt for the client and server, with the server not having any UI code at all, still using the rest of the Qt API extensively.
If you only want it for the collection classes why not just use std:: library?