[SOLVED]Segmentation fault on QQuickView::rootObject()



  • Ok, so, what I'm doing is I have an object QmlGui that has a member QQuickView view, here's the constructor of QmlGui:
    @
    QmlGui::QmlGui() {
    view.setSource(QUrl::fromLocalFile(bin_dir + "/qml/main.qml")); // Set QML source
    view.setResizeMode(QQuickView::SizeRootObjectToView);
    view.show();
    }
    @

    At another point I have:
    @
    QmlGui *qmlGui = new QmlGui();
    @

    Then later, after entering the main Qt loop, there is a call to a function containing the following:

    @
    printf("TEST A\n");
    QObject *view_obj = qmlGui->view.rootObject();
    printf("TEST B\n");
    QObject firstRunDialog = view_obj->findChild<QObject>("firstRunDialog");
    printf("TEST C\n");
    bool result = QMetaObject::invokeMethod(firstRunDialog, "firstRun", Qt::DirectConnection);
    printf("%d\n", result);
    if(result) return 0;
    @

    And it segfaults on the line "QObject *view_obj = qmlGui->view.rootObject();", I don't understand why it's segfaulting here, it really shouldn't be, qmlGui is in scope, so it's not like this function doesn't know about it, qmlGui->view has been fully created/initialized, I have used gdb and it only shows me the line where it segfaults.

    Any help is appreciated, thanks


  • Lifetime Qt Champion

    Hi,

    Since it's a pointer did you allocate qmlGui ?



  • You'll probably have to provide a bit more detail. Show where qmlGui is being declared and defined. If you're segfaulting check to make sure qmlGui isn't null, also check what the other threads in your app are doing.



  • I was under the impression that calling "new QmlGui()" is automatically allocating it.

    Also, I already checked that qmlGui isn't NULL, also, I tried
    @
    if(qmlGui->view == NULL) printf("NULL\n");
    @

    And it threw an error saying something about how a it's a QQuickView and not a pointer, so the compiler recognized that it was a QQuickView.

    Not sure what you mean by checking what my other threads are doing, I only have one thread that I create myself, if there are any other threads they are created by Qt.

    Here's a more full example of what I'm doing:
    Most of my app is C, I have a C++ file connecting it to QML, which was working fine, the first thing that happens is gui_Init():
    @
    //Towards the top of my gui.cpp file I have this:
    QGuiApplication *q_app;
    QmlGui *qmlGui;
    //Making them global variables for this file, so they can easily be accessed from other methods

    //Then later gui_Init()
    int gui_Init(int argc, char **argv) {
    printf("INITIALIZING GUI\n");
    q_app = new QGuiApplication(argc, argv);
    qmlGui = new QmlGui(); // QmlGui is constructed, refer to my constructor in the post above
    q_app->exec(); // Enter main Qt loop, everything is working fine here

    return 0; //After the app closes this is returned to main()
    

    }
    @

    I also have a class GuiConnect which connects to my QML code, making variables and methods accessible from QML. Now in my main.qml file I make a call to a method from GuiConnect (loadApp()) using
    @
    Component.onCompleted: guiConnect.loadApp()// Everything is working fine here
    @

    which calls some functions from my C code, loading data, then if it detects it's the first time the app has been run (in this case it is), it goes to gui_FirstRun() from my gui.cpp file, which has this:
    @
    int gui_FirstRun() {
    printf("TEST A\n"); // This is printed
    QObject *view_obj = qmlGui->view.rootObject(); // This segfaults
    printf("TEST B\n");
    QObject firstRunDialog = view_obj->findChild<QObject>("firstRunDialog");
    printf("TEST C\n");
    bool result = QMetaObject::invokeMethod(firstRunDialog, "firstRun", Qt::DirectConnection);
    printf("%d\n", result);
    if(result) return 0;
    }
    @

    Now I know my app seems complicated, but I assure you I am fully aware of everything I am doing in my app, and am cleaning it up as I go, and I have reasons for writing my app as I am (I started with Gtk, and ended up converting to QML/Qt). Everything in my app is working as expected, up to the segfault.



  • [quote author="KoRnKloWn" date="1371765135"]I was under the impression that calling "new QmlGui()" is automatically allocating it.

    Also, I already checked that qmlGui isn't NULL, also, I tried
    @
    if(qmlGui->view == NULL) printf("NULL\n");
    @

    And it threw an error saying something about how a it's a QQuickView and not a pointer, so the compiler recognized that it was a QQuickView.
    [/quote]

    You're not doing the check properly... It should be:
    @
    if(qmlGui == NULL)
    {
    printf("qmlGui is NULL! \n");
    return 0;
    }
    QObject *view_obj = qmlGui->view.rootObject(); // This segfaults
    @



  • Also, I can't see how gui_firstRun is even being called. You need to provide traceability otherwise we can't tell what's going on.



  • Oh hell...
    This is what I did to check if it was NULL:
    @
    if(qmlGui == NULL) printf("NULL1\n");
    else if(qmlGui->view == NULL) printf("NULL2\n");
    @

    However I was being impatient by doing them both at once, I wasn't thinking about the fact the error was thrown durring compile time and I never had the chance to see NULL1 get printed, I just tried it again with only the first line and of course it's NULL, now that I know that I should pretty easily be able to figure out why it's null and fix it...

    I hate that I get stuck on these issues and it's always something so obvious... -_-



  • Happens :-)



  • OK, so, I was looking over qmlGui, and realized the only thing that was in it was QQuickView, so I just removed the QmlGui class, and instead this:
    @
    //Towards the top of my gui.cpp file:
    QQuickView *view;

    //Then later, where I had qmlGui = new QmlGui()
    view = new QQuickView();

    // And later, where I had qmlGui->view.rootObject() (what was segfaulting)
    QObject *view_obj = view->rootObject();
    @

    Now, it compiles fine, it runs without segfaulting now, however it still doesn't do what's expected, so I checked view and view_obj to see if they were null:
    @
    if(view == NULL) printf("view is NULL\n");
    if(view_obj == NULL) printf("view_obj is NULL\n");
    @

    Now view is not null, but view_obj is, I even tried this:
    @
    if(view->rootObject() == NULL) printf("NULL\n);
    @

    and it was NULL, however when I tried this:
    @
    if(view->engine() == NULL) printf("NULL\n");
    @

    and it was NOT null, so view is being successfully pointed too, but for some reason view->rootObject() keeps returning NULL???



  • Well, I'm finding this new issue to be increasingly difficult to fix, but because my original issue was resolved, I'm going to go ahead and label this thread as solved, the issue was that qmlGui was NULL, and therefore didn't have the QQuickView member. The next issue I'm having I'm experimenting with a different solution other than using QQuickView::rootObject() to connect to the signal, instead I'm working on using Q_PROPERTY(READ and NOTIFY) instead.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.