Symbian 上的 Qt4:(所有)具有文本渲染的应用程序中的 QSymbianLeaveException(KErrAlreadyExists)
你好,祝你有美好的一天。
最近我决定尝试为 symbian 平台(S60 r3)构建 C++/Qt4 应用程序,但是我遇到了一些问题,我不知道如何解决。
问题:
任何应用程序(带有子窗口小部件,例如
QLabel
或QPushButton
),我尝试在手机上启动时立即编译退出。没有任何类型的错误消息,但调试表明程序在某些时候抛出 QSymbianLeaveException ,错误代码为 KErrAlreadyExists。在模拟器中一切正常,或者如果使用hide()
方法隐藏小部件。 Qt SDK 示例可以编译,但不能在手机上运行。空的QWidget仍然可以显示。任何使用
QPainter::drawText()
在QWidget
上渲染文本的尝试都会导致程序以类似的方式“退出”(QSymbianLeaveException,错误代码为KErrAlreadyExists(-11) )。这可能是导致#1 的问题。我仍然可以使用QPainter
绘制线条/圆圈;
软件/硬件设置:
手机:诺基亚 C5-00(Symbian S60 r3 FP2,据我所知)
手机Qt库版本:4.6.3
固件:071.005(2011 年 6 月 4 日)
电脑操作系统: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")); 布局->addWidget(closeButton);`
程序将在手机上运行,我将看到带有“退出”按钮的空白屏幕。
如果我使用
closeButton->hide()
隐藏按钮,应用程序也可以工作,所以显然问题在某种程度上与显示小部件有关。如果我将
paintEvent()
添加到MainWindow
中,只要我不尝试显示任何文本,它就会起作用。调用drawText()将导致应用程序立即抛出QSymbianLeaveException(KErrAlreadyExists):void MainWindow::paintEvent(QPaintEvent *){ QPainter画家(this); Painter.setRenderHint(QPainter::Antialiasing); 画家.setPen(Qt::red); int x1 = 矩形().left(), x2 = 矩形().right(), y1 = 矩形().top(), y2 = 矩形().bottom(); 画家.drawLine(x1, y1, x2, y2); 画家.drawLine(x2, y1, x1, y2); 整数步= 10; 画家.setPen(Qt::green); for (int x = 0; x < x2; x += 10) 画家.drawLine(x, y1, x, y2); for (int y = 0; y < y2; y+= 10) 画家.drawLine(x1, y, x2, y); 画家.setPen(Qt::yellow); Painter.drawEllipse(矩形().center(), 矩形().width()/4, 矩形().height()/4); Painter.drawText(rect().center(), QString("Test"));//这里抛出异常 画家.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 实现,所以我不确定到底是什么导致了这个问题。有想法吗?
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:
Any application (with child widgets such as
QLabel
orQPushButton
) 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 withhide()
methods. Qt SDK examples compile but do not run on cellphone. Empty QWidget can still be displayed.Any attempt to render text on
QWidget
usingQPainter::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 usingQPainter
;
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:
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.
Application also works if I hide the button using
closeButton->hide()
, so apparently the problem is somehow related to displaying widgets.If I add
paintEvent()
toMainWindow
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(); }
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,我在存储卡上安装了自定义字体(覆盖系统默认字体),但完全忘记了它,并且有 是 多个 与字体相关的问题 symbian 上的 Qt 4.6.2 中的自定义字体。删除自定义字体并重新启动手机,现在一切正常。正如我所怀疑的,这是一个配置问题。
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.