2016-03-02 2 views
0

Существует question о том, как привязать свойство singleton к свойству QML. Но как насчет того, чтобы мы привязывали свойство QML к объекту singleton.Как связать свойство с объектом singleton объекта из QML

Вот определение класса синглтон,

class Singleton : public QObject { 
    Q_OBJECT 
    Q_PROPERTY(QString name READ name WRITE setName) 
public: 
    explicit Singleton(QObject *parent = nullptr); 
    QString name() const; 
    void setName(const QString &name); 
private: 
    QString m_name; 
}; 

А на QML

property string qmlName: textField.text 
TextField { 
    id: textField 
} 

Я хотел бы связать textField.text с Singleton объекта name собственности. Можно связать его с обходного как,

onQmlNameChanged: { 
    Singleton.name = qmlName; 
} 

Но это не будет Property Binding на самом деле, потому что это назначение.

Так есть ли более естественный способ привязки к объектно-ориентированному объекту?

+1

На самом деле нет необходимости в свойствах qmlName. Просто команда 'onEditingFinished: {Singleton.name = qmlName}' 'TextField' может выполнять эту работу. – rightaway717

+0

Да, нет необходимости в qmlName, также мы можем написать код на текстовом поле textField, но это не будет привязкой к свойствам. – cavitsinadogru

+0

Что касается сигнала textChanged, возможно, вы не захотите его использовать, кроме «живого поиска», в противном случае, почему посылают сигналы для каждой буквы, если вам нужно целое слово. Что касается привязки свойств, @ddriver объяснил это в значительной степени, так что в этом случае вам просто нравится слово «привязка».Если он делает то же самое под капотом, то в чем разница? – rightaway717

ответ

1

Вы могли бы попытаться присвоить связывание следующим образом:

Component.onCompleted: Singleton.name = Qt.binding(function() { return qmlName }) 

Он работает для нормальных QML-объектов, не уверен, что он работает с одноплодным классом, хотя. Во всяком случае, вы можете больше узнать об этом подходе в разделе "Creating Property Bindings from JavaScript".

0

Это, по сути, то, что связывает свойство, по крайней мере, я предполагаю, что это то, что он делает - он связывает измененные() сигналы связанных переменных для переоценки связанного выражения, которое ссылается на них.

Так что на практике является обязательным:

onQmlNameChanged: { 
    Singleton.name = qmlName; 
} 

У вас будет только проблема, если вы только выполнить задание один раз, но если он присоединен к сигналу он будет продолжать обновлять, как ожидается, форма привязки ,

Это было бы идентично Singleton.name : qmlName, к сожалению, синтаксис QML не позволяет делать это в этой форме. Таким образом, для всех целей и целей у вас есть привязка, даже если для ее достижения используется другой синтаксис.

На самом деле это не должно сильно отличаться от того, что QML делает под ковром для вас. Например, связывание:

someProp : anotherProp + yetAnotherProp

это реализовать, как что-то вроде этого:

function unnamed(this) { return this.anotherProp + this.yetAnotherProp } 
anotherPropChanged.connect(function(this) { this.someProp = unnamed(this) }) 
yetAnotherPropChanged.connect(function(this) { this.someProp = unnamed(this) }) 

Очевидно, что является довольно громоздким, чтобы сделать вручную, особенно как выражение становится все более сложным и референции больше объектов, так QML делает это за вас.

+0

Я не уверен, что это то, что связывает свойство. Я так не думаю, потому что qmlName нужно изменить, поэтому строка Singleton.name = qmlName будет выполнена. Но, с другой стороны, когда мы привязываем свойство, свойство binded также инициализируется с привязанным свойством. Поэтому, чтобы имитировать связывание свойств, мы также должны обходиться с этим. И, во-вторых, это создает постоянную связь между qmlName и Singleton.name, но при связывании свойств это отношение является хрупким, я имею в виду, если мы присваиваем что-либо привязанному свойству, привязка свойств будет нарушена. – cavitsinadogru

+0

Ну да, таким образом, автоматическая оценка по завершению компонента не будет запланирована, вам придется делать это вручную. И да, вам также придется отключать вручную, что возможно только в том случае, если вместо 'onSignal: expr' вы используете' signal.connect (namedFoo) 'так что позже вы можете вызвать' signal.disconnect (namedFoo) '. Выполнение привязки вручную также подразумевает управление им вручную. Если решение, предлагаемое Felix, работает, вы должны пойти с ним, так как он автоматически делает все это для вас. – dtech

+0

да похоже, что решение @Felix более точно. Спасибо, что присоединились к теме. – cavitsinadogru

Смежные вопросы