Associando uma propriedade QML a uma função em C++

No momento o QtQuick não suporta um modo de ligar uma propriedade QML ao resultado de uma função em C++. No entanto, existe uma sugestão para adicionar suporte a este recurso aqui [bugreports.qt.nokia.com] .

Neste artigo, vamos mostrar como viabilizar a associação de propriedades QML e funções usando Q_PROPERTY [doc.qt.nokia.com] juntamente com o sinal NOTIFY [doc.qt.nokia.com] , que é emitido sempre que o valor da propriedade muda.

O Código em C++

Na classe Object no exemplo abaixo, nós criamos uma Q_PROPERTY que é usada para modificar e atualizar o texto do código QML e que tem um sinal changeOfStatus() que é emitido sempre que o status da função em C++ chamada function someFunction() mudar:

  1. Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)

A função Object::getTheChange() modifica o texto de um item QML dependendo do resultado de Object::someFunction(). O resultado é usado como valor do texto da propriedade no código QML.

Object::someFunction() é chamado a partir do QML pois ele usa Q_INVOKABLE [doc.qt.nokia.com]. Ela simplesmente muda o status de uma variável membro, e é chamado a cada 5 segundos usando um QTimer [doc.qt.nokia.com] para ilustrar como a propriedade QML é capaz de reagir à mudança dessa. Ela pode também ser chamada a partir do código QML ao clicar no texto. Por fim, ela emite o sinal changeOfStatus() que aciona Object::getTheChange(), que deve ser chamado quando o texto deve ser reavaliado.

main.cpp

  1. #include <QtGui>
  2. #include <QtDeclarative>
  3.  
  4. class Object : public QObject
  5. {
  6.  Q_OBJECT
  7.   Q_PROPERTY(QString theChange READ getTheChange NOTIFY changeOfStatus)
  8.    
  9. public:
  10.  Object()
  11.  {
  12.   changeMe = false;
  13.   myTimer = new QTimer(this);
  14.   myTimer->start(5000);
  15.   connect(myTimer, SIGNAL(timeout()), this, SLOT(testSlot()));
  16.  }
  17.  
  18.  QString getTheChange()
  19.  {
  20.   if (theValue == 0)
  21.   {
  22.    return "The text changed";
  23.   }
  24.   if (theValue == 1)
  25.   {
  26.    return "New text change";
  27.   }
  28.         return "nothing has happened yet";
  29.  
  30.  }
  31.  
  32.  Q_INVOKABLE void someFunction(int i)
  33.  {
  34.   if ( i == 0) {
  35.    theValue = 0;
  36.   }
  37.   if (i == 1) {
  38.    theValue = 1;
  39.   }
  40.  
  41.   emit changeOfStatus(i);
  42.  }
  43.  
  44. signals:
  45.  void changeOfStatus(int i) ;
  46.  public slots:
  47.   void testSlot()
  48.   {
  49.    if (changeMe)
  50.    {
  51.     someFunction(0);
  52.    } else {
  53.     someFunction(1);
  54.    }
  55.    changeMe = !changeMe;
  56.   }
  57.  
  58. private:
  59.  bool changeMe;
  60.  int theValue;
  61.  QTimer *myTimer;
  62.  
  63. };
  64.  
  65. #include "main.moc"
  66.  
  67. int main(int argc, char** argv)
  68. {
  69.  QApplication app(argc, argv);
  70.  Object myObj;
  71.  QDeclarativeView view;
  72.  view.rootContext()->setContextProperty("rootItem", (QObject *)&myObj);
  73.  view.setSource(QUrl::fromLocalFile("main.qml"));
  74.  view.show();
  75.  return app.exec();
  76.  
  77. }

O Código QML

No código QML abaixo, nós criamos um Rectangle [doc.qt.nokia.com] que reage aos cliques do mouse. O texto é modificado através do resultado da função Object::theChange().

main.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     width: 440; height: 150
  5.  
  6.     Column {
  7.         anchors.fill: parent; spacing: 20
  8.  
  9.         Text {
  10.             text: rootItem.theChange
  11.             font.pointSize: 25; anchors.horizontalCenter: parent.horizontalCenter
  12.  
  13.             }
  14.             }
  15. }

Assim, usando a abordagem do exemplo acima, temos uma maneira de fazer com que propriedades QML reajam a mudanças internas no código C++.

Categories:

  • Tutorial
  • Tutorial
  •