Qt:从 QML 调用槽会导致应用程序崩溃 [数据中止异常]
我正在为 symbian 平台开发 Qt 移动应用程序。我有一个函数可以更改当前显示的屏幕,该函数是一个槽,因此可以从 C++ 端和 QML 调用。
public slots:
void ChangeView(const QString & viewPath);
void Controller::ChangeView(const QString & viewPath) {
if(this->view->status() == QDeclarativeView::Ready) {
QDeclarativeProperty * property = new QDeclarativeProperty(this->view,"source", this->context);
if(property->isValid()) {
property->write(QVariant(viewPath));
property->~QDeclarativeProperty();
}
}
else if(this->view->status() == QDeclarativeView::Error) {
QList<QDeclarativeError> errors = this->view->errors();
for(int i = 0; i < errors.size(); ++i) {
qDebug() << "Error: " << errors.at(i);
}
errors.~QList();
}
}
从 C++ 调用此函数效果很好,
void Controller::Show() {
this->window->setCentralWidget(this->view);
this->menu->MainMenu();
this->ChangeView("qml/Streemio/Login.qml");
this->window->show();
}
但是当我从 QML 调用它时,它会使应用程序崩溃。
Button {
id: channels
anchors.top: nowPlaying.bottom
anchors.topMargin: -1
label: "Channels"
subLabel: "listen to default playlists"
imgSource: "qrc:Streemio/img/channel_menu.png"
fontSize: 14
subFontSize: 7
buttonWidth: container.width
Keys.onSelectPressed: {controller.ChangeView("qml/Streemio/Channels.qml")}
Keys.onDownPressed: {search.focus = true; flickArea.contentY = 75}
Keys.onUpPressed: {nowPlaying.focus = true; flickArea.contentY = 0}
}
这是应用程序的输出。
Starting application...
Application running with pid 770.
CAknSignalDataObserver::HandleUpdateL: UMA
CAknSignalPane::ShowUmaIconL: begin
CAknSignalPane::LoadSignalIconL: uma-off
CAknSignalPane::ShowUmaIconL: end
[Qt Message] QNetworkReplyImpl::_q_startOperation was called more than once
Process 770, thread 771 stopped at 0x71547a2a: A data abort exception has occurred.
Finished.
我在这里做错了什么?谢谢。
I'm working on a Qt mobile app for the symbian platform. I have a function that changes the current screen displayed, this function is a slot and thus can be called from C++ side and from QML.
public slots:
void ChangeView(const QString & viewPath);
void Controller::ChangeView(const QString & viewPath) {
if(this->view->status() == QDeclarativeView::Ready) {
QDeclarativeProperty * property = new QDeclarativeProperty(this->view,"source", this->context);
if(property->isValid()) {
property->write(QVariant(viewPath));
property->~QDeclarativeProperty();
}
}
else if(this->view->status() == QDeclarativeView::Error) {
QList<QDeclarativeError> errors = this->view->errors();
for(int i = 0; i < errors.size(); ++i) {
qDebug() << "Error: " << errors.at(i);
}
errors.~QList();
}
}
Calling this function from C++ works just fine,
void Controller::Show() {
this->window->setCentralWidget(this->view);
this->menu->MainMenu();
this->ChangeView("qml/Streemio/Login.qml");
this->window->show();
}
however it crashes the app when I call it from QML.
Button {
id: channels
anchors.top: nowPlaying.bottom
anchors.topMargin: -1
label: "Channels"
subLabel: "listen to default playlists"
imgSource: "qrc:Streemio/img/channel_menu.png"
fontSize: 14
subFontSize: 7
buttonWidth: container.width
Keys.onSelectPressed: {controller.ChangeView("qml/Streemio/Channels.qml")}
Keys.onDownPressed: {search.focus = true; flickArea.contentY = 75}
Keys.onUpPressed: {nowPlaying.focus = true; flickArea.contentY = 0}
}
Here is the application output.
Starting application...
Application running with pid 770.
CAknSignalDataObserver::HandleUpdateL: UMA
CAknSignalPane::ShowUmaIconL: begin
CAknSignalPane::LoadSignalIconL: uma-off
CAknSignalPane::ShowUmaIconL: end
[Qt Message] QNetworkReplyImpl::_q_startOperation was called more than once
Process 770, thread 771 stopped at 0x71547a2a: A data abort exception has occurred.
Finished.
What am I doing wrong here? Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否正在更改处理按钮按下的视图?如果是这样,则按钮在其按下处理程序中时被破坏并且崩溃。解决方案是让changeView() 方法导致更改异步发生。实现这一点的最简单方法是将实际的视图更改代码放入一个槽中,changeView() 使用 Qt::QueuedConnection 调用。这将导致当前视图被安全地销毁,并在下次进入事件循环时创建新视图。
Are you changing the view that handles the button press? If so then the button is destroyed while in its press handler and it crashes. The solution is to have the changeView() method cause the change to happen asynchronously. The simplest way to achieve that is to put the actual view changing code into a slot which changeView() invokes using Qt::QueuedConnection. That will cause the current view to be safely destroyed and the new view created when the event loop is next entered.
我将在这里进行一个疯狂的猜测,并说有问题的代码行是这一行:
除非你在幕后做了一些非常奇怪的事情,否则这一行可能应该读作
I'm going to take a wild guess here and say that the offending line of code is this one:
Unless you're doing something really freaky behind the scenes this line should probably read