Tjsail33
Tjsail33

Reputation: 21

Switching the Source of a QDeclarativeView

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

Answers (1)

VestniK
VestniK

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

Related Questions