- Qt 4.7 / QML 1.1 application for Symbian Belle, targeting Nokia C7-class devices with self-signed SIS deployment.
- Generated from the
qt-symbian-belle-startertemplate. - See
docs/PLAN.mdfor milestones anddocs/DEVICE_NOTES.mdfor the device experiment log.
- C++ managers in
src/are exposed to QML viasetContextPropertyinmain.cpp:storage(StorageManager),memoryMonitor,tlsChecker, andaudioEngine. StatusNotifier(context propertynotifier, Symbian only) wraps the vendored Pigler Notifications API client insrc/pigler/to show status-panel notifications viashowStatus(title, subtitle)andclearStatus().StorageManagerhandles SQLite with a multi-candidate writable-path fallback.- QML uses Symbian Components 1.1.
AppWindow.qmlis the root, and pages live inqml/. - Qt 4 has no
QJsonDocument; use the vendoredlib/qjsonlibrary for native JSON. - See
docs/QT4_SYMBIAN_PRACTICES.mdfor reusable networking, qrc, file URL, and device-verification practices.
- Never write the
positionproperty on a QMLAudioelement. This causesKErrMMAudioDevice(-12014) and can break all audio until the phone restarts. Drive playback through the C++audioEnginewithQMediaPlayer::setPosition(). - Data caging:
/private/<UID>/directories are writable but invisible toQDir::exists(). Skipexists()/mkpath()checks and go straight to an I/O test. - SQL driver: prefer
QSYMSQLoverQSQLITEon Symbian. Tests should use the same driver as production code. - Path separators: use
QDir::toNativeSeparators()for paths passed to SQL drivers on Symbian. - Hardware volume keys are RemCon media keys, not window-server key events. A QML
Keyshandler orRWindowGroup::CaptureKeysees nothing. Register aCRemConCoreApiTargetviaCRemConInterfaceSelector::OpenTargetL()only afterview.show()plusQApplication::processEvents(); registering before the window is foreground causes the first few presses to be silently dropped until focus re-resolves. - The app icon cache is sticky. Symbian's AppArc icon cache is keyed by UID and does not reliably refresh on a plain reinstall over an existing install, even with a version bump. A report that an icon fix "isn't showing up" needs a full uninstall, reboot, then reinstall — not a code re-diagnosis first.
- The Simulator build excludes all
#ifdef Q_OS_SYMBIANcode. A greenbuild-simulator.ps1run does not validate native Symbian-only code such as RemCon handling, data-caged paths, or QSYMSQL. Compile-check any Symbian-only edit withscripts/build-symbian.ps1before requesting a device SIS build; this only proves compilation, not runtime behavior, and device round-trips are expensive.
- No block expressions in property bindings. Use a helper function or ternary.
- No named function declarations inside non-root elements. Declare functions only at the
Pageor root level. - No negative anchor margins. Size a larger
Itemfor touch targets instead. - SVG icon sizing: Symbian renders icons using the SVG
viewBoxdimensions and ignoreswidth/height. To resize, change bothwidth/heightandviewBox, wrapping paths in<g transform="scale(factor)">. - Use
double, notqreal, for QML-facing numeric properties. On Symbian,qrealisfloat; moc encodesQ_PROPERTY(qreal ...)asQMetaType::QReal, which overflows RVCT4's signed metadata expression and emits warning#61-D. Keep the property, accessors, parameters, locals, and backing storage consistently typed asdouble. font.pixelSizemust be an int. A fractional value such as12.5throwsInvalid property assignment: int expectedat load time, which silently fails the entire containing page (Type <Page> unavailable), not just that element. Round fractional design sizes when porting.- New
.qmlfiles need aqml.qrcentry. QML loads from the Qt resource system, not the filesystem, so a file missing fromqml/qml.qrcmakespageStack.push(...)orinitialPagesilently fail with "File not found" and no crash; the page simply never appears. - List and grid delegates need one full-delegate
MouseArea. Anchor a singleMouseAreato fill the whole delegate root, placed first so it sits behind the visual content, so taps anywhere on the row register. A partial hit target scoped to only part of the row reads as "not tappable" on a small screen. - Pair every
openSoftwareInputPanel()call with acloseSoftwareInputPanel(). On Symbian the on-screen keyboard opens on a click reaching aTextInput, not onforceActiveFocus()alone, which is desktop/simulator-only behavior. If the panel is never explicitly closed on page exit, it stays "visible" and keeps reserving viewport height on the next page, clipping content underneath it.
- Status-panel notifications use the Pigler Notifications API (PNA), a separate on-device server the user installs (
Pigler.sisfrom nnproject.cc/pna). The app degrades gracefully without it. StatusNotifier(context propertynotifier) wraps the vendoredQPiglerAPI(src/pigler/, from upstreampiglerorg/pigler). All Pigler code is under#ifdef Q_OS_SYMBIAN; off-Symbian the class is a no-op so the simulator still builds.- Build: vendored sources plus
LIBS += -lrandom -laknnotifygo only in thesymbian {}scope ofBelleApp.pro; no extra capability needed. - Gotcha — removeOnTap: Pigler's server default is remove-on-tap, so a tap deletes the notification. For a persistent one, call
setRemoveOnTap(id, false)(StatusNotifieralready does this inshowStatus()). - Gotcha — slots behind
#ifdef: moc processes headers on every platform, but a slot declared inside#ifdef Q_OS_SYMBIANis missing from the meta-object on other platforms, so a string-basedconnect(SIGNAL(...), SLOT(...))wires up to nothing, silently, at runtime. Declare such slots unconditionally and guard only the body. Compile-checks (both simulator and ARM) will not catch this.
- After any audio, media, or platform API experiment, record the result in
docs/DEVICE_NOTES.mdwith a dated heading in the form## YYYY-MM-DD - Title. - Include error codes and failed approaches in the log.
- Read
docs/DEVICE_NOTES.mdbefore touching audio or media code because Symbian MMF behavior is fragile.