使根 QML 组件的功能可被其他组件调用

Posted

技术标签:

【中文标题】使根 QML 组件的功能可被其他组件调用【英文标题】:Make function of root QML component callable for other components 【发布时间】:2011-04-10 14:20:42 【问题描述】:

我想显示一个消息框,它在 ma​​in.qml 中实现(作为所有其他组件之上的一个层)。函数showMessage() 使QML 消息框可见并设置文本。所以 ma​​in.qml 中的代码可以显示消息框,但其他组件(不在 ma​​in.qml 中)也应该能够显示消息框。

到目前为止,我的想法是创建一个 C++ QML 组件,该组件具有一个函数 displayMessage(),它调用根上下文的 showMessage() 函数 (→ ma​​in.qml)。

ma​​il.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 全局对象?)

谢谢!


编辑:

我想我找到了一个非常简单的解决方案:由于 QML 是一种动态范围的语言 (→ Qt Doc) 并且所有组件都嵌套在 ma​​in.qml 中,所以这很简单:

ma​​in.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】:

Radon,你找到了正确的解决方案,没错。我在这里推荐的增强功能是将您的消息框移动到一个名为 MessageBox.qml 的单独文件中,然后在 main.qml 中声明 MessageBox 组件并通过其 ID 直接引用您的消息框,而不是创建额外的 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);
    

对我来说,它提高了代码的可读性和结构,并允许您摆脱在 main.qml 中使用的 QtObject,从而使代码紧凑。如果你需要一些东西来“提升”你的消息框,而不是使用包装器,你可以使用z property of Item element。

希望这会让你的代码看起来更好。

【讨论】:

以上是关于使根 QML 组件的功能可被其他组件调用的主要内容,如果未能解决你的问题,请参考以下文章

QDeclarativeItem 中的 OpenGL 绘图搞乱了其他 QML 绘图

Qml自定义组件 - ListView下拉刷新 - PullToRefreshHandler

qml 对多个对象使用相同的矩形组件

深入微服务-SpringCloud调用组件Feign

vue 怎么调用其他组件的方法

QML Popup弹窗置于最顶层,实现点击位置该弹出窗口下方的任何其他层组件,Popup弹窗都不会关闭