开发者

Make function of root QML component callable for other components

开发者 https://www.devze.com 2023-02-23 03:26 出处:网络
I want to show a message box, that is implemented in main.qml (a开发者_C百科s a layer above all other components). The function showMessage() makes the QML message box visible and sets the text. So it

I want to show a message box, that is implemented in main.qml (a开发者_C百科s a layer above all other components). The function showMessage() makes the QML message box visible and sets the text. So it's possible for code in main.qml to show message boxes, but other components (not in main.qml) should be able to show message boxes, too.

My idea so far is to create a C++ QML component that has a function displayMessage() which calls the showMessage() function of the root context (→ main.qml).

mail.qml (root component)

import QtQuick 1.0
// [...]

Rectangle {
    id: main

    function showMessage(text) {
        // make a message area visible and set text
    }

    // [...]

    // message box implementation
}

App.qml

import QtQuick 1.0
import MessageForwarder 1.0  // implemented in C++
// [...]

Rectangle {
    id: anApp

    MessageForwarder { id: mf }  // ← Possible without this? 

    Component.onCompleted: mf.displayMessage("A message."); // show message

    // [...]
}

Is it possible to create something like a static function, that would allow something like MessageForwarder.displayMessage("Foo"), without needing an additional instance of the MessageForwarder component?

Or is there any other convenient possibility to use showMessage() in other components?

(Maybe something like the Qt global object?)

Thanks!


EDIT:

I think I found a quite simple solution: As QML is a dynamically scoped language (→ Qt Doc) and all components are nested inside main.qml, this simply works:

main.qml

import QtQuick 1.0

Rectangle {
    id: main

    QtObject { 
        id: messageBox
        // nested for a more modular design
        function showMessage(text) {
            // make a message area visible and set text
        }
    }

    // [...]

    // message box implementation
}

App.qml

import QtQuick 1.0

Rectangle {
    id: anApp

    Component.onCompleted: messageBox.showMessage("A message.");

    // [...]
}


Radon, you found the right solution, true. What I may recommend here as an enhancement is to move you message box to a separate file called say MessageBox.qml, and then declare MessageBox component in main.qml and refer to your message box by its ID directly instead of creating additional QtObject element and refer to the actual message box through it. For example:

// MessageBox.qml
Item {
    property string headerText
    property string messageText
    ...
    Text {
        ...
    }
    ... 
    function show(headerText, bodyText, mode) {
        ...
    }
}

And then use it in you main.qml as:

// main.qml
Rectangle {
   id: main
   MessageBox { id: messageBox } // a very compact declaration of you MessageBox
   ...
}

And then call it in any file of you app like this:

//NetworkConnectionsWindow.qml
Rectangle {
    ...
    onError: {
        ...
        // and here you refer to you global message box object
        messageBox.show('Network error', 'Server is not responding', ErrorMode);
    }
}

To me, it improves the code readability and structure and allows you to get rid of QtObject that you're using in main.qml making the code compact. If you need something to "raise" your message box, instead of using a wrapper thing you can use z property of Item element.

Hope that would make your code look nicer.

0

精彩评论

暂无评论...
验证码 换一张
取 消