UPDATE (24th May, 10.20pm EST): Corrected some errors below.
I was looking at how to integrate custom OpenGL content inside a Qt Quick 2 application. Qt Quick 2 has several solutions, and settled on a custom OpenGL underlay. However, one stumbling block was that I wanted to use OpenGL 4.3 core profile. On my test machine, the driver supports OpenGL 4.4 and I discovered that by default Qt Quick 2 created a 4.4 compatibility profile context.
After much searching, I finally found the solution I was looking for. I am not sure if it is the only way or the optimal way, but it worked for me. You can specify the OpenGL propeties including the desired profile by creating a QSurfaceFormat object and passing it to QQuickWindow object using setFormat before Qt Quick’s scene graph begins rendering, i.e. before you invoke QQuickWindow::show either in C++, or before you set “visible” property of the window to true in QML.
The next question was, how to get to the window. Here is how to do so in some scenarios:
- If you have a handle to any QQuickItem inside the window, then simply call the “window” method.
- If you have created your application using Qt Quick Controls ApplicationWindow, and are using QQmlApplicationEngine to load the QML, make sure “visible” property of the ApplicationWindow is set to false in the QML. Then, simply get the first root object from the engine using something like
engine->rootObjects().first(). This is your window object and you can simply cast it to QQuickWindow.
- If you have created your application using QQuickView, well then your are in luck because QQuickView is a QQuickWindow so just call setFormat on the QQuickView.
Once you have done setFormat, you are then free to call “show” on the QQuickWindow and it will make your window visible.
I had previously noted that I installed Qt Creator 3.0 and it automatically detected compiler toolchains, CMake etc. At that time I was running VS 2010 Professional. I recently moved to VS 2013 Express. I opened up a new CMake project in Qt Creator and noticed that suddenly it no longer gave me the option for the proper NMake generator and started failing. After much mucking about, I have finally discovered the solution and just documenting it here in case someone else comes across the same issue.
The solution is simple. Simply install the newly released Qt Creator 3.1. Qt Creator 3.1 has inbuilt support for detecting and using VS 2013 compilers with CMake. Qt Creator 3.0 detects the compilers succesfully but was not really passing the right arguments to CMake or something. Anyway, after updating to 3.1, all my CMake projects work now.
I have been using Qt Creator on Linux for a while now for my C++ based projects. Qt Creator has a nice editor with fairly speedy autocomplete and good refactoring support. I typically use CMake and Qt Creator has decent support for CMake under both Windows and Linux and also has decent integration with tools like mercurial. On WIndows, however, I was using Visual Studio (either 2010 or 2013 depending on the project dependencies) for C++. While VS has a nice debugger, its editing and refactoring functionality for C++ is quite behind Qt Creator in my experience. I finally got around to using Qt Creator on WIndows, even for non-Qt projects and I find that it offers the same great experience on Windows. The install process was pretty painless and Qt Creator detected all my tools (various VS versions, CMake binary etc.).
Kudos to Digia and Qt Project for the great tools. I am constantly amazed at the quality of work they put out. I only use VS now for occasionally debugging. Thoughts welcome.
Finally I have managed to port a small desktop app to Android and Blackberry 10. The app was based on QWidgets and was based on Qt 4.8. The app was not for open distribution unfortunately so I can’t share the app. However, I can share some experiences:
Blackberry 10: I just changed to the Blackberry-provided qmake, ran qmake and make, and the app compiled without any changes for Blackberry 10. However, packaging the app requires a few additional steps. You have to obtain signing keys (which I already had), provide a bar-descriptor.xml and then run the blackberry-nativepackager command. The process is generally well-documented and went fine. I was able to test on a Blackberry Z10. I initially ran into an issue that I had forgotten to specify the proper permissions in the bar-descriptor for accessing files, but once I corrected it things ran “ok”. Most of the widgets actually rendered fine and layout scheme worked as expected. However, things were not perfect either. For example, the file picker dialog was not very nice but at least the app was servicable. The lack of integration with BB10 UI conventions is an issue though so will have to see if there is a way to integrate stuff like swipe-down menus from a pure QWidget (or perhaps Qt Quick 1/2) based app without using Cascades.
Android: For Android, I used Android 5.1 and actually used Qt Creator 2.8.1 to set everything up. Changing to Qt 5.1 required very minimal changes such as a couple of ifdefs for changed header file names. Qt Creator asked for Android SDK and NDK paths, and after that setup most of the things automatically including inbuilt simulator support. If you connect a device over adb, those are recognized as well for deployment and testing. Qt Creator was automatically generating unsigned APKs but doesn’t seem to generate signed apk’s, or at least I couldn’t figure out how.
Overall, things were going smoothly on Android .. until I actually ran the app. Turns out QWIdgets look really ugly on Android and some of the layouting doesn’t really work the way you would want. Some widgets, like QComboBox used for implementing drop-down menus, did not render correctly while some others like file dialogs were ugly and almost unusable. After a few careful changes, I was able to make it work but still integration was poor.
I would say, at least on Android, you should try to avoid QWidgets and start to use QML. QML will allow you far more control over the look, feel and layout of your app. I do hope that something like Qt Quick Controls come to Android because raw QML is a bit too much DIY. The other issue is that, I am still not clear on how Qt based apps can integrate with Android UI guidelines such as integration with the back button. I am also not clear how you can integrate, say, invoking the email application or the web browser. Need to figure these out next.
I am quite excited about Blackberry 10. RIM’s development tools are looking pretty good. As a C++ programmer, I am pleased with my initial experience with the toolchain. Blackberry 10 comes with a full Qt 4.8 implementation in the firmware. As a Qt programmer, you have 3 options to write apps for BB10:
- Use Cascades. Cascades is a proprietary (but quite cool) UI framework built by RIM. It uses QML as it’s markup but does not use the QML painting engine at all. Instead, it uses its own painting engine and it is incompatible with QWidget and Qt Quick frameworks. You can either use Cascades to show the UI, or you can use Qt’s painting engine (QtGui or Qt Quick), but not both. However, you can still use QtCore and QtNetwork etc in your app. I experimented a little bit with Cascades and it is pretty nice. For Cascades, I recommend that you simply use QNX Momentics IDE provided by RIM as part of the standard NDK download. However, I have decided not to pursue this route as I wanted my code to be platform independent. Currently I am a single developer working on Qt projects for fun, and I am preferring to maintain a single code base across platforms as much as possible.
- Use QWidget. QtGui module (the basis of QWidget) is fully supported but if you use QWidget, you cannot use Cascades.
- Use Qt Quick (perhaps with some QWidgets thrown in). This is also supported but will again exclude the use of Cascades.
If you are interested in options 2 or 3 (QWidget or Qt Quick), then I recommend that you use Qt Creator. I tested with Qt Creator 2.6.1 on Ubuntu 12.04 64-bit and things are working fine. I have not managed to get QWidget and Qt Quick working under QNX Momentics, there are always some compilation or build errors for non-Cascades project.
There are some good instructions to configure Qt Creator in NDK documentation as well as on the Qt Project Wiki. I do not have a BB10 device but I was able to compile a QWidget based app in Qt Creator and run in the BB10 simulator.
One piece of advise: ignore the “simulator-debug” configuration section mentioned on the Qt Project Wiki. It appears to be required only for Cascades projects. Trying to make that section work in a QWidget based app wasted a lot of my time. In the end, I omitted it and things started working. I simply defined the BB10 kit in Qt Creator as described, modified the bar-description.xml example given in the NDK official documentation about porting Qt apps, then added a “blackberry-x86-qcc” spec to QMake as recommended by the Qt Project wiki, and everything worked brilliantly.
I have not yet tried compiling a Qt Quick based application for BB10, but I think process of compiling a Qt Quick app should be similar to the QWidget app above.