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?
Related
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 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.
I know it's possible to write your code in C++ and use Objective C to make native Mac UI and Visual C++ to make native Windows UI.
Can someone please point me to a tutorial or write a sample code that teaches how to do this?
NOTE
I know about Qt or wxWidgets but that isn't the solution I want. I really really want to give a native feeling.
Although you say you know about Qt and wxWidgets, I still recommend you use them. You can do native-feeling apps with them.
You will always have to implement some kind of abstraction layer since the Windows and Mac are vastly different in how their UIs are implemented. You would need to find common patterns, find ways on how to abstract things so that different things can be accessed in a similar way. For this, you need to know both Windows and Mac programming very well. You will spend a lot of time trying to find workarounds and searching bugs. With every new iteration of Windows or Mac OS X, you would need to start working around bugs and/or integrating new behavior yet again.
Using a cross-platform library will save you lots of time and trouble and thus money, if you're writing a commercial application.
Edit: Well, if you're forced to go that route, I'd recommend to do it like this:
Separate the app into two parts: a backend that doesn't know anything about UI which does all the business logic and then the UI part. You would need to implement the UIs completely separate from each other and wouldn't be able to share much code between them. After all, if you would try to find common grounds (for example, if you would like to unify creating and using a button) you could as well use a cross-platform UI library again...
The upside would be that you could use every obscure UI feature available to each OS. The downside would be that you need to maintain two UIs, so if you add a feature to one UI you'd need to reimplement it in the other as well.
But you might want use a cross-platform library for the backend to unify things like file handling, networking and threading.
So I've fooled around with WPF a bit recently, and I must say that I really like the idea. I love the framework as a whole, from the GUI to the plumbing.
However, as much as I love managed land, I love my native code just as much. So I'm wondering what sort of libraries exists for C++ which capture the essence of various parts of WPF. I'm not looking for interop solution, nor do I want Managed C++ or C++/CLI solutions, but pure C++ solutions.
Now, I'm not expecting to find a "copy" of WPF for C++ - I wouldn't expect that to exist, nor would I need it to. Instead, I would expect that different libraries might capture a subset of the desired concepts. My particular interests are
Hardware accelerated graphics for widget based GUI's (via DirectX or OpenGL, preferably the latter)
Declarative language for GUI design (preferably an XML dialect)
Data binding
Resolution independence (less important)
To say a little about my reasoning, I would like to implement such a library myself, which captures a specific model that I have begun working out. I am in the process of finding some more inspiration and helpful resources before locking down my design. The library is intended to be cross-platform, so references to cross-platform ideas would be great, but not strictly necessary as I am usually capable of translating things into cross-platform solutions.
Lastly, although I am writing a C++ library, and C++ ideas would be great, I am open to ideas from any native language.
Thanks in advance for any help.
There isn't really anything like this. Not cross-platform at any rate. Direct2D works reasonably well, but is obviously Windows-only. And NVIDIA recently dropped this "path" extension of OpenGL that is similar in basic functionality, but it is NVIDIA-only (and not available on Mac OSX). Cairo has an OpenGL backend, but I have no idea how good it is. It can't be that good if Mozilla dumped Cairo in favor of D2D on Windows.
Many GUI toolkits have some form of language for making a GUI. Qt has one that is pre-compiled into C++.
Not that I know of. Data binding requires some form of reflection (WPF-style data binding does), and C++ has no native support for reflection. So you would need to implement reflection of some sort before you can even begin to make WPF-style data binding work.
That comes with #1. More or less, as any GPU-based renderer will be able to operate at arbitrary resolutions.
I love C++, but honestly, this sort of thing is best implemented for a higher level language. The lack of language-based reflection support will make implementing data binding a huge pain. Whereas, you could just implement the low-level "render stuff to area" and basic window/event management in C++, then expose it to a scripting language where data binding and such work. That way, you have native code speed where you need it, but the versatility and reflection of a scripting language for dealing with the GUI and its associated data.
I'm several years late, but for the benefit of anybody else reading this question: you're looking for Qt Quick / QML:
http://qt-project.org/doc/qt-4.8/qml-intro.html
http://doc.qt.io/qt-5/qtqml-cppintegration-topic.html
First off: I'm new to both Qt and SWIG. Currently reading documentation for both of these, but this is a time consuming task, so I'm looking for some spoilers. It's good to know up-front whether something just won't work.
I'm attempting to formulate a modular architecture for some in-house software. The core components are in C++ and exposed via SWIG to Python for experimentation and rapid prototyping of new components. Qt seems like it has some classes I could use to avoid re-inventing the wheel too much here, but I'm concerned about how some of the bits will fit together.
Specifically, if I create some C++ classes, I'll need to expose them via SWIG. Some of these classes likely subclass Qt classes or otherwise have Qt stuff exposed in their public interfaces. This seems like it could raise some complications.
There are already two interfaces for Qt in Python, PyQt and PySide. Will probably use PySide for licensing reasons. About how painful should I expect it to be to get a SWIG-wrapped custom subclass of a Qt class to play nice with either of these? What complications should I know about upfront?
PyQt exposes C++ code to Python via SIP; PySide does so via Shiboken. Both have roughly the same capabilities as SWIG (except that they only support "extended C++ to Python", while SWIG has back-ends for Ruby, Perl, Java, and so forth as well). Neither SWIG nor SIP and Shiboken are designed to interoperate with each other. You couldn't conveniently use SWIG to wrap any code using the C++ extensions that Qt requires (to support signals and slots) and I have no idea what perils may await you in trying to interoperate SIP-wrapped (or Shiboken-wrapped) and SWIG-wrapped code.
Why, may I ask, have you chosen to use two separate and equivalent ways to wrap different parts of your C++ codebase (Qt via SIP or Shiboken, everything else via SWIG)? If you can still reconsider this weird design decision I would earnestly recommend that you do so.
If your choice of SWIG is carved in stone, I predict big trouble any time you're wrapping C++ code using Qt extensions (i.e., slots or signals) and a generally thoroughly miserable time for all involved. If you pick one way to wrap, and stick with it, the problems should be enormously reduced. I have no real-world experience with Shiboken (it's a bit too new, and I hardly ever do GUI apps these days any more... my world's all web app!-), but have used SIP in this role in the past (way back before it was decently documented -- these days it seems to me that it's splendidly documented, and superficial perusal of Shiboken gives me the same impression) and I can recommend it highly (indeed if I could choose it would be an option probably preferable to SWIG even if no Qt code was involved in a project).