Symbian上的Qt4:带有文本渲染的(所有)应用程序中的QSymbianLeaveException(KErrAlreadyExists)

时间:2011-08-29 16:47:20

标签: c++ qt4 symbian s60

你好,祝你好运。

最近我决定尝试为symbian平台(S60 r3)构建C ++ / Qt4应用程序,但是我遇到了一些我不确定如何修复的问题。

问题

  1. 任何应用程序(包含QLabelQPushButton等子窗口小部件)我尝试在手机上启动时立即编译退出。没有任何类型的错误消息,但调试表明在某些时候程序抛出QSymbianLeaveException,错误代码为KErrAlreadyExists。一切都在模拟器中工作正常,或者如果使用hide()方法隐藏小部件。 Qt SDK示例编译但不在手机上运行。仍然可以显示空QWidget。

  2. 使用QWidgetQPainter::drawText()上呈现文本的任何尝试都会导致程序以类似的方式“退出”(QSymbianLeaveException,错误代码为KErrAlreadyExists(-11))。这可能是造成#1的问题。我仍然可以使用QPainter;

  3. 绘制线条/圆圈

    软件/硬件设置:
    手机:诺基亚C5-00(Symbian S60 r3 FP2,AFAIK)
    手机Qt库版本:4.6.3
    固件:071.005(04-Jun-2011)
    PC OS:WinXP SP3
    QtCreator版本:2.0.1
    申请TRK版本:3.1.2
    TRK API版本:3.5

    示例
    以下代码编译并在模拟器中正常工作,但不在手机上:

    项目文件:

    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
    

    应用输出

    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.
    

    调试结果:

    1. 根据我的调试结果,应用程序在w.showMaximized()处抛出QSymbianLeaveException。没有错误消息。如果我注释掉那些行:

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

      程序将在手机上运行,​​我将通过“退出”按钮进入空白屏幕。

    2. 如果我使用closeButton->hide()隐藏按钮,应用程序也可以工作,所以显然这个问题与显示小部件有关。

    3. 如果我将paintEvent()添加到MainWindow,只要我不尝试显示任何文字,它就能正常工作。对drawText()的调用将导致应用程序立即抛出QSymbianLeaveException(KErrAlreadyExists):

      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. 尝试构建QFontDatabase也会导致应用程序抛出相同的错误。

    5. 其他信息

      错误代码(KErrAlreadyExists)的提取方式如下:

      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);
          }
      

      那么,这个问题的原因是什么,我该如何解决?我终于设法从这个问题中找到了一些意义(至少现在我有错误代码),但是我无法在调试器中完成Qt实现,所以我不确定究竟是什么确切地导致了这个问题。想法?

1 个答案:

答案 0 :(得分:3)

事实证明我已将自定义字体(覆盖系统默认字体)安装到存储卡上并完全忘记了它,并且are multiple problems与字体和自定义字体相关联在Qt 4.6.2中关于symbian。删除自定义字体并重新启动手机,现在一切正常。我怀疑这是一个配置问题。