Qt World Summit: Register Today!

[SOLVED]QQuickView with qmlRegisterType, signal not working in QML

  • I'm working on an app, where the entire gui is QML, I'm using C++ QT just to connect the QML to the rest of my app. It's coming along, but I keep running into little road blocks, the latest of which is connecting a signal from a registered class (using qmlRegisterType) to my QML.
    Here is the relavant code from my gui.cpp:
    @QGuiApplication *q_app_ptr;
    void gui_Init(int argc, char **argv) {
    static QGuiApplication q_app(argc, argv);
    q_app_ptr = &q_app;

    // Prepare QT C++ for import in QML
    qmlRegisterType<QmlConnect>("QmlConnect", 1, 0, "QmlConnect");

    // Start QML app
    static QQuickView view;

    And of course later in the program I have @q_app_ptr->exec();@

    Then the relavant code from my gui.h:
    @class QmlConnect : public QObject {
    Q_PROPERTY(QStringList getData READ getData NOTIFY dataChanged)

    QmlConnect(QObject *parent = 0){}

    QStringList getData() {
    static QStringList data_list;
    data_list << "Data1" << "Data2" << "Data3" << "Data4";
    return data_list;

    void dataChanged();

    And here is my gui.qml:
    @import QtQuick 2.0
    import Ubuntu.Components 0.1
    import Ubuntu.Components.ListItems 0.1 as ListItem

    import QmlConnect 1.0

    MainView {
    objectName: "mainView"
    // applicationName: "My App"
    id: root

    width: units.gu(100)
    height: units.gu(80)

    property real margins: units.gu(2)
    property real buttonWidth: units.gu(9)

    // Instantiate QmlConnect
    QmlConnect {
    id: qmlConnect
    onDataChanged: {
    console.log("DATA LIST CHANGED\n");

    // Component.onCompleted:

    Column {
    id: libraryColumn
    ListItem.Header {text: "Library"}
    ListItem.Standard {text: "List1"}
    ListItem.Standard {text: "List2"}
    ListItem.Divider {}
    ListItem.Header {text: "Lists"}

    width: units.gu(10)
    anchors {
    left: parent.left
    top: parent.top
    bottom: parent.bottom
    Grid {
    id: browserGrid
    Component.onCompleted: {
    var data_list = qmlConnect.getData;
    // for(var i = 0; i < data_list.length; i++) {
    // console.log(data_list[i]);
    // }

    Then later in my app I have:
    @QmlConnect qmlConnect;
    emit qmlConnect.dataChanged();@

    Now when I uncomment
    @for(var i = 0; i < data_list.length; i++) {

    It successfully prints the data (of course it gets stuck in a loop printing it, but I'm not really worried about that right now, that was just to see if it was successfully importing the registered class and able to call a function from it). But never once is "DATA LIST CHANGED\n" printed, however if I put printf("TEST\n"); after emit qmlConnect.dataChanged();, it prints "TEST\n" so I know that part of the code is running.

    Does emit qmlConnect.dataChanged(); have to appear after exec()??? Because I have that at the very end of my program, and the emit is happening before exec() is called.

  • Yes. You have to call exec before any user interaction can take place. Have a look at "QGUIApplication::exec":http://qt-project.org/doc/qt-5.0/qtgui/qguiapplication.html#exec.

    Just a note... it is Qt and not QT.

  • Thanks, as you can probably tell I'm pretty new to Qt, and actually C++, most of my app is in C, the C++ is just a wrapper to connect the QML to my C app. I actually read that before but I overlooked it because I'm not using the signal for user interaction, but for interaction with the rest of my program, I just need to come at this from another angle I guess.

    Other than that fact, does it look like I'm doing it right? How I have
    @onDataChanged: {
    console.log("DATA LIST CHANGED\n");

    inside of QmlConnect{} ???

    And thanks for the help, I search Google and these forums and the Qt documentation quite a lot before I ever post questions, but what I'm doing isn't real common so there aren't a lot of examples.

  • User interaction usually triggers Qt's signal/slot mechanism. So before that can work you must call exec. Your signal will not do anything if you call it before calling exec.

    Your setup looks to be on the correct path.

    Have a look at "this":http://qt-project.org/forums/viewthread/27001/

    And "this":http://qt-project.org/forums/viewthread/26191/

  • Thanks I didn't have a clue what a singleton was, but after lookign over that second link in the singleton example it makes a lot of sense, and I think that may be what I will ultimately need.

Log in to reply