I use QML for PhotProc. The app is mostly targeting Symbian, which QML works very well for. But, it would be good if PhotProc worked on other platforms. One user asked for it to be available on Windows, because it processes very very large images quite well. I assumed this would be easy, but it turns out to be surprisingly hard.
The problem is that under Symbian, QML programmers use Symbian-specific classes. If you put the import for those Symbian-specific classes in your QML files, you get an error under Windows. This breaks pretty much everything when doing cross-platform development.
What you can't do in QML is what you would do in C++, which is use a #ifdef for each platform. You're not allowed to do that.
Instead, what I did, was use some features of QML, with some directory hacking, which looks a little ugly, but actually turned out quite well in the end!
The first step is to take all of your platform-specific components and put them in a directory. If you want a button, create your own button class and put that in its own QML file. Then, use that QML class in your app instead of platform-specific buttons. This lets you use Symbian-specific buttons on Symbian, and write your own button QML classes for other platforms using things like MouseArea.
The problem is, how do you get each platform to "see" a different set of QML classes. The solution I chose was to "deploy" a different platform-specific directory for each platform.
Here's what my QML directory structure looks like:
QML
^-PhotProc - this is all of my cross-platform QML files
^-PlatformSpecific - this is where I put platform-specific QML files that Qt Creator sees
^-Symbian
..^-PlatformSpecific - this is where I put the Symbian platform-specific QML files
^-Windows
..^-PlatformSpecific - this is where I put the Windows platform-specific QML files
I have a "FilterButton" class. I have 3 versions of it: one is in "PlatformSpecific", one in "Symbian/PlatformSpecific" and one in "Windows/PlatformSpecific". The version in "PlatformSpecific" is going to be seen by QtCreator. This seemed nasty, but turns out quite well: it means I can make a nice icon in QtCreator, even for very complex QML files that QtCreator would previously not be able to cope with "inside" another QML file.
The last trick is to ensure that when building for each platform, the "PlatformSpecific" directory is taken from the right platform. I assumed the solution is to store this in per-platform build-settings, but it seems those are stored in the .user file which should not be checked into source control as it's supposed to be user-specific. So, instead, I have to detect the platform in the .pro file. This is harder than it sounds, because the Symbian "simulator" returns the platform the simulator is running under, not the platform that's being simulated. Luckily, it appears as a "simulator" platform.
This is how my .pro file starts:
# Add more folders to ship with the application, here
folder_01.source = qml/PhotProc
folder_01.target = qml
# these are the platform-specific folders
DEPLOYMENTFOLDERS = folder_01
PHOTPROCTARGET=Windows
symbian{
PHOTPROCTARGET=Symbian
}
simulator{
PHOTPROCTARGET=Symbian
}
contains (PHOTPROCTARGET, Symbian){
# should only be used on Symbian and simulator
folder_02.source = qml/Symbian/PlatformSpecific
folder_02.target = qml
DEPLOYMENTFOLDERS += folder_02
QML_IMPORT_PATH = qml/PlatformSpecific
DEFINES += QML_PLATFORM="Symbian"
}
contains (PHOTPROCTARGET, Windows){
# should only be used on Windows desktop
folder_02.source = qml/Windows/PlatformSpecific
folder_02.target = qml
DEPLOYMENTFOLDERS += folder_02
QML_IMPORT_PATH = qml/PlatformSpecific
DEFINES += QML_PLATFORM="Windows"
}