久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

QML中的兩種方式綁定C++模型

Two way binding C++ model in QML(QML中的兩種方式綁定C++模型)
本文介紹了QML中的兩種方式綁定C++模型的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我正在嘗試更多地了解 QtQuick 和 QML.我目前的目標是了解如何將數據從 C++ 模型綁定到我的視圖.到目前為止,我已經能夠在我的 QML 中設置模型并從模型中獲取數據,但我不知道如何更新我的數據.

I'm trying to learn more about QtQuick and QML. My current goal is to understand how to bind data from a C++ model to my view. So far I've been able to setup the model in my QML and get data from the model but I can't figure out how to update my data.

如何為我的 C++ 模型設置雙向綁定?以下是我目前編寫的代碼.

How do I setup two way binding for my C++ model? Below is the code I've written so far.

message.h

class Message : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString author READ getAuthor WRITE setAuthor NOTIFY authorChanged)
    Q_PROPERTY(QString message READ getMessage WRITE setMessage NOTIFY messageChanged)

    Q_SIGNALS:
        void authorChanged(QString author);
        void messageChanged(QString message);

    public:
        Message(QObject *parent = 0);

        QString getAuthor();
        void setAuthor(QString author);

        QString getMessage();
        void setMessage(QString message);

    private:
        QString _author;
        QString _message;
};

message.cpp

#include "message.h"

Message::Message(QObject *parent) : QObject(parent)
{
}

QString Message::getAuthor()
{
    return _author;
}

void Message::setAuthor(QString author)
{
    if(author != _author)
    {
        _author = author;
        emit authorChanged(author);
    }
}

QString Message::getMessage()
{
    return _message;
}

void Message::setMessage(QString message)
{
    if(message != _message)
    {
        _message = message;
        emit messageChanged(message);
    }
}

ma??in.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import com.butts.messaging 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: "Test"

    Message {
        id: testMessage
        author: "Batman"
        message: "Hello World!"
    }

    Flow {
        TextField {
            text: testMessage.message
        }

        Label {
            text: testMessage.message
        }
    }
}

ma??in.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "message.h"

int main(int argc, char *argv[])
{
    qmlRegisterType<Message>("com.butts.messaging", 1, 0, "Message");

    //Message msg = Message();

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));

    return app.exec();
}

附言我在這方面是個大菜鳥,所以請隨時指出我的代碼中的任何其他問題(格式、標準等),我需要以某種方式學習哈哈

P.S. I'm a giant noob at this so feel free to point out any other issues (formatting, standards, etc.) I have in my code, I need to learn somehow lol

編輯 1

閱讀@derM 的回答后,我更改了代碼以實現我想要的

After reading @derM's answer I changed my code to achieve what I wanted

TextField {
    id: editor

    //Binding model -> view
    text: testMessage.message

    //Binding model <- view
    Binding {
        target: testMessage
        property: "message"
        value: editor.text
    }
}

Label {
    id: display

    //Binding model -> view
    text: testMessage.message
}

推薦答案

雙向綁定在 QML 中是一個復雜的問題,因為它通常用作某種賦值.

Twoway binding is a complicated matter in QML, as it usually works as some assignment.

所以,如果你用 propertyname: valuetobeboundto 綁定一個屬性,然后再給 propertyname 賦值,這個綁定就會丟失.

So, if you bind a property with propertyname: valuetobeboundto and later assign something to propertyname again, this binding will be lost.

解決方法有兩種:使用綁定-對象或不使用綁定,但手動處理所有屬性更改信號(理想情況下您的模型正確發出).

As a workaround there are two ways: The use of Binding-Objects or to not use binding, but handle all the property-change-signals (which your model ideally properly emits) manually.

首先,您可以在此處找到詳細說明.在這里,他們為每個方向使用一個 Binding-Object.好消息是,那些 Binding 不會通過分配新的 Binding 被覆蓋.

For the first, you can find a detailed instruction here. Here they use the one Binding-Object for each direction. The good thing is, those Bindings will not be overridden, by assignment of a new Binding.

考慮:

Row {
    spacing: 2
    Rectangle {
        id: r0
        width: 50
        height: 30
    }

    Rectangle {
        id: r1
        width: 50
        height: 30
        color: b2.pressed ? 'red' : 'blue'
    }

    Button {
        id: b2
    }

    Button {
        id: b3
        onPressed: r1.color = 'black'
        onReleased: r1.color = 'green'
    }

    Binding {
        target: r0
        property: 'color'
        value: b2.pressed ? 'red' : 'blue'
    }


    Binding {
        target: r0
        property: 'color'
        value: (b3.pressed ? 'black' : 'green')
    }
}

開始時r1的值綁定到b2的狀態,但是一旦b3被按下,r1 不會再通過點擊 b2 更新.對于r0,更新將由兩個Binding-Objects 完成,因此Binding 不會丟失.但是,您可以看到綁定是如何工作的:每當 Button 的狀態發生變化時,Binding 都會更新.因此按下 AND 釋放 b2 將觸發信號,該信號將由第一個 Binding 處理,按下 也是如此b3 的 >AND 發布.

At the beginning the value of r1 is bound to the state of b2, but as soon as b3 has been pressed once, r1 won't be updated by a click on b2 anymore. For r0 the updating will be done by the two Binding-Objects, and therefore the Binding won't be lost. However, you can see, how the binding works: When ever the state of the Button changes, the Binding will be updated. So the press AND the release of b2 will fire signals, that will be handled by the first Binding and the same goes for the press AND relase of b3.

現在來到雙向綁定.在這里,避免綁定循環很重要.

Now coming to the two-way binding. Here it is important to avoid Binding-Loops.

Row {
    Button {
        id: count0
        property int count: 0
        onClicked: count += 1
        text: count
    }

    Button {
        id: count1
        property int count: 0
        onClicked: count += 1
        text: count
    }

    Binding {
        target: count0
        property: 'count'
        value: count1.count
    }

    Binding {
        target: count1
        property: 'count'
        value: count0.count
    }
}

雖然這個例子非常好.count0.count 的變化會觸發count1.count 的變化.現在檢查,如果count0.count 需要更新,但值已經是正確的,所以遞歸結束,并且沒有發生綁定循環.

While this example is perfectly fine. The changing of count0.count will trigger a change of count1.count. Now it is checked, if count0.count would need an update, but the value is already the right, so the recursion ends, and no binding-loop occures.

將第二個綁定更改為

    Binding {
        target: count1
        property: 'count'
        value: count0.count + 1
    }

徹底改變情況:現在隨著count0.count 的每次變化,count1.count 需要提高.第一個 Binding 然后嘗試將 count0.count 設置為與 count1.count 相同的值,但是沒有辦法讓 Binding 就滿足了,其他的Binding 完成后不需要做任何改變.這將導致綁定循環.幸運的是,這些在 QML 中檢測得很好,因此避免了鎖定.

drastically changes the situation: Now with each change of count0.count, count1.count needs to be raised. The first Binding then tries to set count0.count to the same value as count1.count but there is just no way that both Binding will be satisfied, and no change is needed to be done, after the other Binding did it's work. It will result in a binding-loop. Luckily those are detected pretty fine in QML, so a lock is avoided.

現在只需要處理最后一件事:考慮這個組件定義:

Now there is only one last thing to take care of: Consider this Component-Definition:

// TestObj.qml
Item {
    width: 150
    height: 40
    property alias color: rect.color
    Row {
        spacing: 10
        Rectangle {
            id: rect
            width: 40
            height: 40
            radius: 20
            color: butt.pressed ? 'green' : 'red'
        }
        Button {
            id: butt
            text: 'toggle'
        }
    }
}

這里我們有一個 color-property 的內部綁定,通過使用 propertyname: valueToBeBoundTo-Syntax.這意味著,內部綁定可能會被 color 屬性的任何外部賦值覆蓋.用 Binding-Object 替換這個綁定,你應該沒問題.

Here we have an internal binding of the color-property, by using the propertyname: valueToBeBoundTo-Syntax. This means, the internal binding might be overwritten by any external assignemtn of the color-property. Replace this binding by a Binding-Object, and you should be fine.

反之亦然:color 在外部綁定到某個值,然后您在內部處理一個信號并為其分配一個值,如果沒有,外部綁定將丟失由 Binding-Object 創建.

The same would go the other way around: color is externally bound to some value, and then you handle a signal internally and assign a value to it, the external binding would be lost, if not created by a Binding-Object.

這只是一般概述.還有更多細節可能會改變綁定的行為.但我想我已經展示了如何創建雙向綁定并提到了一些您可能會遇到的陷阱.

This is only a general overview. There are way more details that might alter the behavior of Binding. But I think I have shown, how you can create a Two-Way-Binding and mentioned quite some pitfalls, you might encounter.

這篇關于QML中的兩種方式綁定C++模型的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數據?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環: for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環?)
Reusing thread in loop c++(在循環 C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環形?)
主站蜘蛛池模板: 国产成人一区二区三区 | 亚洲精品99 | 亚洲精品一区二区三区 | 男人的天堂久久 | 天天艹逼网 | 色婷婷九月 | 91久久国产 | 国产精品久久久久免费 | 一区二区三区视频在线观看 | 日韩精品一区二区三区在线播放 | 黄网站免费观看 | 日本亚洲精品成人欧美一区 | 91视频国产一区 | 国产不卡一区在线观看 | 精品久久久久久久久久久 | 日韩免费视频 | 日日夜夜天天久久 | 欧美中文在线 | 国产亚洲精品综合一区 | 99tv| 久久久久国产 | 中文区中文字幕免费看 | 日韩一区二区三区视频 | 久久久久国产精品 | 日韩一区二区三区av | 欧美一级三级 | 国产亚洲欧美另类一区二区三区 | 日本不卡视频在线播放 | 91亚洲欧美| 一区二区三区在线电影 | 国产资源在线观看 | 久久久久久久一区二区三区 | 日韩爱爱网| 久久久久久久久久久高潮一区二区 | 一区二区中文字幕 | 一区二区三区欧美在线 | 亚洲高清视频在线 | 国产在线精品一区二区三区 | 日本一区二区视频 | 国产高清视频一区 | 亚洲一区二区久久 |