Native Symbian Dialogs in Qt Apps
This article explains how to launch native Symbian C++ dialogs from within a Qt QWidget based application.
Not every Symbian native dialog is present in the standard Qt widget library, and in any case these dialogs do not always sufficiently match the look and feel of the Symbian native dialogs. If the native widget is not available or suitable, one alternative is to directly launch the native Symbian dialog from your Qt code.
Showing a standard native Symbian note dialog is easy, as those can be setup and instantiated only from the source code - this article explains how to do that through the example of a confirmation note dialog.
If a definition in a Symbian resource file is required or recommended (e.g., for progress dialogs), several steps are necessary to make it work - this article will guide you through the necessary steps.
Download the attached example, which demonstrates showing a Symbian progress / wait dialog from a Qt Hello World app. The key steps are explained here. The example can be self-signed. Use at least Qt SDK 1.1 (final) and ensure you enable the "Native API Support" in the Symbian Toolchains section of the Qt SDK Maintenance tool.
Symbian Resource File
Create a new file in your project, e.g. “dialogs_<UID>.rss”. Adding the Symbian UID3 to the filename is recommended, as the standard directory for resource files is shared between all installed apps. As your UID is unique on the system, you avoid any potential filename conflicts. In this example, the UID3 of the app is 0xee0861b3 (as defined in the .pro file as TARGET.UID3).
The file needs to have certain elements defined at the top to make it a valid Symbian resource file (NAME, RSS_SIGNATURE, TBUF16). Add your own definition of the dialog below. Here, our dialog definition is called: r_wait_note_softkey_cancel
// Don't forget those two resources, which are required to make this
// file a valid Symbian resource file. These have to be defined before
// you define any own resources!
buf = "";
// The definition of our own wait dialog with a cancel softkey
// Read the Symbian documentation for more details on the dialog definitions.
RESOURCE DIALOG r_wait_note_softkey_cancel
flags = EAknWaitNoteFlags;
buttons = R_AVKON_SOFTKEYS_CANCEL;
type = EAknCtNote;
id = EMyAppWaitNote;
layout = EWaitLayout;
singular_label = "Wait...";
animation = R_QGN_GRAF_WAIT_BAR_ANIM;
The hrh file contains control ids, so that they can be referenced from both the source code as well as the resource file (if needed). Here, we define only one control in a new file called nativesymbiandlg.hrh. In this example, we don't access the control id from the source code, as we don't need to dynamically adapt the dialog or to retrieve user entered content from it.
// Define the ID of the control
EMyAppWaitNote = 0x100
Qt .pro file
In the project file, several additions are needed when compiling for Symbian:
- Add native Symbian libs required for calling the dialogs
- Add code so that the resource file gets compiled by the Symbian resource compiler
- Deploy the compiled resource file from the Nokia Qt SDK to the \resource\apps\ folder on the device (the ! as the drive letter means that the file is going to be copied to the drive the user / Nokia Store selects for installation – usually, either C: or E:)
- Also include the .hrh file for the compilation
TARGET.UID3 = 0xee0861b3
LIBS += -lcone \
rssresources = "SOURCEPATH ." \
"START RESOURCE dialogs_ee0861b3.rss" \
"TARGETPATH resource\apps" \
MMP_RULES += rssresources
addFiles.pkg_postrules = "\"/NokiaQtSDK/Symbian/SDK/epoc32/data/z/resource/apps/dialogs_ee0861b3.rsc\" - \"!:\\resource\\apps\\dialogs_ee0861b3.rsc\""
DEPLOYMENT += addFiles
OTHER_FILES += nativesymbiandlg.hrh
Load the resource file
In the main(), you need to load your additional resource file so that its contents can be utilized from your app. In the .pro file, we specified that the resource file should be deployed to the drive the user / Nokia Store selects during installation. Therefore, we need to dynamically retrieve the installation drive and make sure we load the file from the correct drive. The code to add the correct path and drive to the resource file name, plus to load the file has been written in a new loadSymbianResourceFile() method:
void loadSymbianResourceFile(const QString& resFileName)
// Convert the QString parameter to a descriptor
TPtrC resFileNameDescriptor (reinterpret_cast<const TText*>(resFileName.constData()), resFileName.length());
// Resource file path (drive letter will be replaced if necessary)
// Get the full path and name of the executable - using this to determine the resource file
// path. Assumes that resource files are installed to the same dir as the exe.
TFileName appNamePath = CEikonEnv::Static()->EikAppUi()->Application()->AppFullName();
// Convert the path to a modifiable descriptor
// Replace the drive letter with the letter from the app path
resFile = appNamePath;
//resFile.Replace(0, 1, appNamePath);
// Add the actual filename of the resource file to the path
// Want to see the filename that will be loaded? Uncomment the following two lines
// to convert the descriptor to a QString and output it to the debug stream.
// Don't forget to also uncomment the QDebug include statement at the top of this file.
//qDebug() << resFileQt;
// Load the resource file and convert the potential leave to a exception
int main(int argc, char *argv)
QApplication a(argc, argv);
// Load the Symbian resource file - only specify the name of the compiled resource file
// Don't forget to add the deployment to the .pro file to actually copy the file
// to the right directory on the device.
Showing the dialog on the screen
In the main window class, we now load the dialog definition from the resource file and show it on the screen. The m_waitDialog variable is defined as an instance variable in the header file (not visible here). Note the dialog ID specified when executing the dialog is the same as specified in the resource file - the only difference is that it's now written in uppercase letters. This transformation is automatically applied by the resource compiler. If you're interested, you can take a look at the id definition if you search for the dialogs_<UID>.rsg file, which is automatically created in the SDK directory during compilation.
MainWindow::MainWindow(QWidget *parent) :
// Create a new instance of the S60 wait dialog class
m_waitDialog = new CAknWaitDialog(REINTERPRET_CAST(CEikDialog**, &m_waitDialog));
// If creation was successful...
// (we don't use the (ELeave) here, as the only reason for it would be to check if
// creating the instance was successful and if not throwing a Symbian Leave.
// In a Qt app, this would then have to be converted to a C++ exception and handled
// somewhere as well. Far easier in this simple case to just check manually if
// creation was successful.)
// Execute the dialog, specifying the resource ID that is defined in the .rss
// file (here written in uppercase, as it's converted to by the resource compiler.
// See the real ID that's used here in dialogs_ee0861b3.rsg)
// The D at the end of this call means that the dialog will be destroyed
// automatically after it's dismissed.
// If the dialog is still active, finish it so that it's automatically deleted.
When you launch the app, it will load the UI (in the example app simply a label with the “Hello World” text) and show an indefinite progress dialog on top. The dialog can either be cancelled by the user, or will also be dismissed when the window is destructed. Note that this example only works when executed on a Symbian device - you can not use the simulator to test it, as the simulator isn't based on the Symbian OS. The downloadable example contains additional #ifdefs so that you can compile the app also for the simulator (the dialog won't be shown then) - these have been omitted in the code snippets shown above.
Import the test app to your Qt Creator as part of the Qt SDK. If needed, adapt the source location of the resource file in the Qt .pro to the installation directory of your Nokia Qt SDK. File:NativeSymbianDlg.zip