Сделать функцию корневого компонента QML вызываемой для других компонентов - PullRequest
3 голосов
/ 10 апреля 2011

Я хочу показать окно сообщения, которое реализовано в main.qml (как слой над всеми другими компонентами). Функция showMessage() делает окно сообщения QML видимым и устанавливает текст. Таким образом, код в main.qml может отображать окна сообщений, но другие компоненты (кроме main.qml ) также могут отображать окна сообщений.

Моя идея на данный момент заключается в создании компонента C ++ QML, который имеет функцию displayMessage(), которая вызывает функцию showMessage() корневого контекста (→ main.qml ).

mail.qml (корневой компонент)

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

    // [...]
}

Можно ли создать что-то вроде статической функции, которая позволила бы что-то вроде MessageForwarder.displayMessage("Foo"), без необходимости дополнительного экземпляра компонента MessageForwarder?

Или есть другая удобная возможность использовать showMessage() в других компонентах?
(Может быть, что-то вроде Qt глобального объекта?)

Спасибо!


EDIT:

Мне кажется, я нашел довольно простое решение: поскольку QML - это динамически ограниченный язык (→ Qt Doc ), а все компоненты вложены в main.qml , это просто работает:

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.");

    // [...]
}

1 Ответ

5 голосов
/ 10 апреля 2011

Радон, ты нашел правильное решение, правда. В качестве усовершенствования я могу порекомендовать вам переместить это окно сообщения в отдельный файл с именем, скажем, MessageBox.qml, а затем объявить компонент MessageBox в main.qml и обратиться к окну сообщения напрямую по его идентификатору вместо создания дополнительного элемента QtObject обратитесь к фактическому окну сообщения через него. Например:

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

А затем используйте его в main.qml как:

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

А затем назовите его в любом файле вашего приложения, например:

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

Для меня это улучшает читаемость и структуру кода и позволяет вам избавиться от QtObject, который вы используете в main.qml, делая код компактным. Если вам нужно что-то, чтобы «поднять» окно сообщения, вместо использования обертки вы можете использовать свойство z элемента Item .

Надеюсь, что ваш код будет выглядеть лучше.

...