Reputation: 21
First question here, so bear with me.
I have been trying to create a view on a QMainWindow using a QDeclarativeView as the canvas, but whenever I try to switch the source of the QDeclarativeView my program segfaults and I frankly have no idea why, or how to fix it.
Here is my swapView() function.
void MainWindow::swapView(int view)
{
switch (view)
{
case 0:
cout << "Switching to Slideshow..." << endl;
this->setSource("Slideshow.qml");
break;
case 1:
cout << "Switching to Main Canvas..." << endl;
this->setSource("Test.qml");
cout << "Successfully switched to Main Canvas!" << endl;
break;
}
}
Here is the setSource() method that it is calling:
void MainWindow::setSource(QString fileName)
{
this->ui->declarativeView->setSource(QUrl::fromLocalFile("Test.qml"));
}
I tried replacing the code above with the code below, and it gets rid of the segfault, but each window opens in a separate window instead of just replacing the view on the QDeclarativeView.
void MainWindow::setSource(QString fileName)
{
QDeclarativeView *view = new QDeclarativeView;
view->setSource(QUrl::fromLocalFile(fileName));
ui->declarativeView = view;
ui->declarativeView->show();
}
If anyone has any input on what I'm doing wrong (I'm sure it's something stupid), please let me know...
Thanks.
Upvotes: 2
Views: 1203
Reputation: 1920
Looks like this crash is caused by destruction of an C++ object managed by the old document inside this object method. In my case I have MuseArea which triggers a slot in my C++ code which switches source document. Something like this crashes:
QML code:
MouseArea {
anchors.fill: parent
onClicked: cppObject.action()
}
C++ code
QDeclarativeView * viewInstance();
class CppObject: public QObject {
Q_OBJECT
public slots:
void action() { viewInstance()->setSource("another.qml") }
};
The way to fix it is to use queued connection somewhere between code called by QML event and setSource call. The following code works well:
QML code:
MouseArea {
anchors.fill: parent
onClicked: cppObject.actionNeeded()
}
C++ code
QDeclarativeView * viewInstance();
class CppObject: public QObject {
Q_OBJECT
public:
explicit CppObject(QObject *parent = 0) : QObject(parent)
{
connect(
this,SIGNAL(actionNeeded()),
this,SLOT(action()),
Qt::QueuedConnection
);
}
public slots:
void action() { viewInstance()->setSource("another.qml") }
signals:
void actionNeeded();
};
Upvotes: 4