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.
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:
property->~QDeclarativeProperty();
Unless you're doing something really freaky behind the scenes this line should probably read
delete property;
精彩评论