你好,祝你好运。
最近我决定尝试为symbian平台(S60 r3)构建C ++ / Qt4应用程序,但是我遇到了一些我不确定如何修复的问题。
问题:
任何应用程序(包含QLabel
或QPushButton
等子窗口小部件)我尝试在手机上启动时立即编译退出。没有任何类型的错误消息,但调试表明在某些时候程序抛出QSymbianLeaveException,错误代码为KErrAlreadyExists。一切都在模拟器中工作正常,或者如果使用hide()
方法隐藏小部件。 Qt SDK示例编译但不在手机上运行。仍然可以显示空QWidget。
使用QWidget
在QPainter::drawText()
上呈现文本的任何尝试都会导致程序以类似的方式“退出”(QSymbianLeaveException,错误代码为KErrAlreadyExists(-11))。这可能是造成#1的问题。我仍然可以使用QPainter
;
软件/硬件设置:
手机:诺基亚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.
调试结果:
根据我的调试结果,应用程序在w.showMaximized()
处抛出QSymbianLeaveException。没有错误消息。如果我注释掉那些行:
QPushButton* closeButton = new QPushButton(tr("C&lose"));
layout->addWidget(closeButton);`
程序将在手机上运行,我将通过“退出”按钮进入空白屏幕。
如果我使用closeButton->hide()
隐藏按钮,应用程序也可以工作,所以显然这个问题与显示小部件有关。
如果我将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();
}
尝试构建QFontDatabase也会导致应用程序抛出相同的错误。
其他信息:
错误代码(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实现,所以我不确定究竟是什么确切地导致了这个问题。想法?