c++qt4symbians60

Qt4 on Symbian: QSymbianLeaveException(KErrAlreadyExists) in (all) applications with text rendering


Hello and good day to you.

Recently I decided to try building C++/Qt4 applications for symbian platform (S60 r3), however I got a few problems I'm not sure how to fix.

Problems:

  1. Any application (with child widgets such as QLabel or QPushButton) I try to compile quits immediately when launched on a cellphone. There are no error messages of any kind, but debugging has shown that at some point program throws QSymbianLeaveException with error code KErrAlreadyExists. Everything works fine in simulator or if widgets are hidden with hide() methods. Qt SDK examples compile but do not run on cellphone. Empty QWidget can still be displayed.

  2. Any attempt to render text on QWidget using QPainter::drawText()causes program to "quit" in similar fashion(QSymbianLeaveException with error code KErrAlreadyExists (-11)). That could be the problem that causes #1. I can still paint lines/circles using QPainter;

Software/Hardware setup:
Cellphone: Nokia C5-00 (Symbian S60 r3 FP2, AFAIK)
Cellphone Qt Libraries version: 4.6.3
Firmware: 071.005 (04-Jun-2011)
PC OS: WinXP SP3
QtCreator version: 2.0.1
Application TRK version: 3.1.2
TRK API version: 3.5

Example:
Following code compiles and works fine in simulator, but not on the cellphone:

project file:

QT       += core gui

TARGET = QtSymTest
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

CONFIG += mobility
MOBILITY = 

symbian {
    TARGET.UID3 = 0xe6e84812
    # TARGET.CAPABILITY += 
    TARGET.EPOCSTACKSIZE = 0x14000
    TARGET.EPOCHEAPSIZE = 0x020000 0x800000
}

main.cpp:

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[]){
        QApplication a(argc, argv);
        MainWindow w;
#if defined(Q_WS_S60)
        w.showMaximized();//application "quits" here
#else
        w.show();
#endif
        return a.exec();
}

mainwindow.cpp:

#include "mainwindow.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
: QWidget(parent){
    QHBoxLayout* layout = new QHBoxLayout();
    QPushButton* closeButton = new QPushButton(tr("C&lose"));
    layout->addWidget(closeButton);
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    setLayout(layout);
}

MainWindow::~MainWindow(){                 
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QWidget>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
};

#endif // MAINWINDOW_H

Application output:

Executable file: 7185 2011-08-29T20:28:12 D:\development\NokiaQtSDK\Symbian\SDK\epoc32\release\gcce\udeb\QtSymTest.exe
Package: 7632 2011-08-29T20:31:44 D:\development\projects\QtSymTest\QtSymTest.sis
Deploying application to 'Nokia C5-00 USB Serial Port (COM6)'...
Copying installation file...
Installing application...
Starting application...
Application running with pid 4958.
Finished.

Debugging results:

  1. According to my debugging results, application throws QSymbianLeaveException at the w.showMaximized(). There are no error messages. If I comment out those lines:

    QPushButton* closeButton = new QPushButton(tr("C&lose"));
    layout->addWidget(closeButton);`
    

    Program will run on cellphone and I'll get empty screen with "Exit" button.

  2. Application also works if I hide the button using closeButton->hide(), so apparently the problem is somehow related to displaying widgets.

  3. If I add paintEvent() to MainWindow it will work, as long as I don't try to display any text. A call to drawText() will cause application to throw QSymbianLeaveException(KErrAlreadyExists) immediately:

    void MainWindow::paintEvent(QPaintEvent *){
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setPen(Qt::red);
        int x1 = rect().left(), x2 = rect().right(), y1 = rect().top(), y2 = rect().bottom();
        painter.drawLine(x1, y1, x2, y2);
        painter.drawLine(x2, y1, x1, y2);
        int step = 10;
        painter.setPen(Qt::green);
        for (int x = 0; x < x2; x += 10)
            painter.drawLine(x, y1, x, y2);
    
        for (int y = 0; y < y2; y+= 10)
            painter.drawLine(x1, y, x2, y);
    
        painter.setPen(Qt::yellow);
        painter.drawEllipse(rect().center(), rect().width()/4, rect().height()/4);
    
        painter.drawText(rect().center(), QString("Test"));//exception is thrown here
    
        painter.end();
    }
    
  4. Trying to construct QFontDatabase also causes application to throw same error.

Additional info:

Error code (KErrAlreadyExists) were extracted like this:

void processError(const std::exception& e){
    int errCode = qt_symbian_exception2Error(e);
    QString str = QString("%1: %2 , %3").arg(e.what()).arg(errCode).arg(intSize);
    QString name = typeid(e).name();
    qDebug() << e.what();//nothing gets printed in debugger at this point
    qDebug() << typeid(e).name();//but I can see values of str/name in watch window
}

...

    try{
        painter.drawText(30, 30, "Test");//application quits here
    }
    catch(std::exception &e){
        processError(e);
    }

So, what is the cause of this problem and how do I fix it? I finally managed to make some sense out of this problem (at least now I have error code), but I can't walk through Qt implementation in debugger so I'm not sure what exactly sure what exactly causes that problem. Ideas?


Solution

  • It turns out I had installed a custom font (overriding system default font) onto memory card and completely forgot about it, and there are multiple problems associated with fonts and custom fonts in Qt 4.6.2 on symbian. Removed custom font and rebooted the phone, now everything works fine. As I suspected, it was a configuration problem.