Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Portuguese
  4. Q_PROPERTY, qual sua real vantagem?
Forum Updated to NodeBB v4.3 + New Features

Q_PROPERTY, qual sua real vantagem?

Scheduled Pinned Locked Moved Portuguese
11 Posts 6 Posters 4.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    Exotic_Devel
    wrote on last edited by
    #1

    Durante uma pesquisa para descobrir se Qt disponibiliza algum recurso para o clichê get e set, descobri a macro Q_PROPERTY. Li parte da documentação (confesso que não li tudo) e não entendi qual é a vantagem proposta, visto que ainda se tem que escrever os métodos gets e sets. Eu esperava algo que poupasse o trabalho como os recursos do C# e Python.
    Não entendi o que Q_PROPERTY se propõe a fazer. Meta objeto é um recurso do Qt que ainda não entendo bem como funciona.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      Arnaut
      wrote on last edited by
      #2

      bq. Não entendi o que Q_PROPERTY se propõe a fazer

      De acordo com o meu entendimento, Q_PROPERTY é a solução que os engenheiros do Qt criaram para resolver alguns dos seus próprios problemas como por exemplo editar widgets no Qt-Designer.

      Se você não está interessado em criar plugins para o Qt-Designer e nem usando o QtScript eu vejo só dois motivos para usar Q_PROPERTY:

      • a possibilidade de se atribuir o valor de uma Q_PROPERTY usando um style sheet
      • a possibilidade de criar um style sheet que considera o valor das propriedades do widget.

      H.

      1 Reply Last reply
      0
      • E Offline
        E Offline
        Exotic_Devel
        wrote on last edited by
        #3

        Então para uma simples classe 'Pessoa' e seus atributos (ex. nome, sobrenome, sexo) Q_PROPERTY não é a solução?

        1 Reply Last reply
        0
        • T Offline
          T Offline
          TioRoy
          wrote on last edited by
          #4

          O Q_PROPERTY cria a idéia de propriedade, semelhantemente como existe em outras linguagens anotadas como C#/Python/Java.

          Em C#, se você cria uma classe assim:
          @
          public class Test
          {
          public String Nome { get; set; }
          public String Telefone { get; set; }
          }
          @

          Nome e Telefone são propriedades.

          Se escrever assim:

          @
          public class Test
          {
          public String Nome;
          public String Telefone;
          }
          @

          São membros públicos

          São a mesma coisa? Não.

          Por exemplo: No C#, por que preciso criar uma propriedade em vez de um membro? Membros não são serializados automaticamente, e propriedades sim. Além disso, membros públicos podem ser acessados. Numa propriedade, você pode restringir o acesso, tornando a mesma "read-only".

          O Q_PROPERTY faz a mesma coisa: dar o sentido de propriedade à classe (e não simplesmente um membro). E anota a classe

          É usado, por exemplo, quando você escreve um objeto em C++ e usa ele no QML.

          1 Reply Last reply
          0
          • E Offline
            E Offline
            Exotic_Devel
            wrote on last edited by
            #5

            Entendi, só não consigo ver qual o beneficio em fazer uso do Q_PROPERTY ou optar por criar uma classe C++ simples. Exemplo:

            @ class Pessoa {
            public:
            QString getNome();
            int getIdade();
            QChar getSexo();
            void setName(QString nome);
            void setIdade(int idade);
            void setSexo(QChar sexo);
            private:
            QString nome;
            int idade;
            QChar sexo;
            };
            @

            A única ocasião que me vem à mente onde Q_PROPERTY seria necessário é caso fosse necessário acompanhar em tempo de execução as mudanças nas propriedades do objeto, para disparar um evento qualquer por exemplo.
            Mas como trata-se unicamente de um objeto de transferência (DTO) para persistência, não vejo necessidade.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              danieltm64
              wrote on last edited by
              #6

              Suponhamos que você crie um novo widget que desenha um círculo, assim:

              @class Circulo : public QWidget
              {
              Q_OBJECT
              public:
              explicit Circulo(QWidget *parent = 0);

              // propriedade "raio"
              double raio() const;            // get
              void setRaio(double raio);      // set
              
              // propriedade "cor"
              QColor cor() const;             // get
              void setCor(const QColor &cor); // set
              
              // função responsável por desenhar o widget
              virtual void paintEvent(QPaintEvent *event);
              

              private:
              double m_raio;
              QColor m_cor;
              }@

              Agora suponhamos que você deseja arrastar e soltar esse widget no Qt Designer (ou no modo "Design" do Qt Creator), assim como você faria com qualquer outro widget. Como o Qt Designer vai conseguir te mostrar todas as propriedades que você pode editar (raio e cor)? Quando você arrasta um "Push Button" e solta ele na sua janela, você vê a propriedade "text" na lista de propriedades que fica no canto inferior-direito porque essa propriedade foi marcada com Q_PROPERTY, sem isso não tem como o Qt Designer adivinhar quais funções são os getters e setters dos diversos membros privados.

              Outro benefício do Q_PROPERTY é no QML. Suponha o seguinte código em QML.

              @import QtQuick 2.0

              Rectangle {
              id: retangulo
              width: 100
              height: 100

              Text {
                  id: texto
                  text: retangulo.width
              }
              

              }@

              Nesse caso, toda vez que a largura do retangulo mudar, o texto será atualizado para mostrar a nova largura do retangulo. Como o Qt saberá que a largura mudou? Porque a propriedade "width" foi marcado com Q_PROPERTY, assim:

              Q_PROPERTY(qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)

              Na verdade, a linha de código acima faz parte do QQuickItem, mas Rectangle é um tipo de QQuickItem. Enfim, veja que nessa linha de código o NOTIFY indica qual signal é emitido quando a propriedade "width" mudar. Assim, sempre que a largura do retangulo mudar (ou seja, quando o signal dado for emitido), o Qt reavaliará todas as expressões que dependem da largura. No exemplo acima, o Qt é capaz de atualizar o texto para a nova largura do retangulo assim que a largura mudar, e sim, isso ocorre em tempo real.

              Esses são alguns dos benefícios do Q_PROPERTY, devem haver outros. Se você não precisa de integrar seu widget no Qt Designer ou se você não quiser fazer um tipo de item em QML, então usando Q_PROPERTY não faria mal mas provavelmente seria desnecessário. Para uma simples classe que guarda alguns dados em uma aplicação realmente não vejo necessidade de usar Q_PROPERTY.

              Daniel

              1 Reply Last reply
              0
              • E Offline
                E Offline
                Exotic_Devel
                wrote on last edited by
                #7

                Grato pela resposta daniel era o que eu queria saber.
                Quando resolvi procurar por este assunto, na verdade eu buscava algo referente a sintaxe, como no caso do C# citado pelo TioRoy. Eu buscava por saber se Qt implementava alguma solução para evitar as várias linha de código com get e set, imagine um classe com 10 atributos... dói só de pensar.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  danieltm64
                  wrote on last edited by
                  #8

                  É, C++ não oferece um recurso para propriedades diretamente como o C#, mas o Qt Creator tem uma opção para implementar uma propriedade automaticamente. Por exemplo, digite o seguinte na sua classe:

                  @Q_PROPERTY(int exemplo READ exemplo WRITE setExemplo)@

                  e depois, com o cursor em cima do Q_PROPERTY, pressione Alt+Enter, aparecerá um menu, agora pressione Enter novamente. O Qt Creator então criará um membro privado e funções para get e set que fazem uso do membro privado. Depois de criado esse membro privado e essas funções get e set, você pode remover o Q_PROPERTY da sua classe mas não tem necessidade. Outra forma de fazer isso é clicar com o botão direito no Q_PROPERTY e dentro do submenu 'Refactoring' você clica em 'Generate Missing Q_PROPERTY Members...'.

                  Quando o Qt Creator cria código para propriedades desse jeito, ele sempre dá o nome 'arg' para o argumento da função que faz o set, então talvez você queira ajustar isso para que seu código fique mais elegante. Talvez você queira acrescentar uma lógica mais sofisticada para as funções get e set, depende do que você precisa, mas essa é uma forma rápida e fácil de criar propriedades básicas.

                  Daniel

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    micdoug
                    wrote on last edited by
                    #9

                    O objetivo maior do Q_PROPERTY é prover um mecanismo de reflexão, de tal forma que se consiga conhecer a estrutura interna de um objeto qualquer em tempo de execução.

                    Quando utilizamos a macro Q_PROPERTY em conjunto com Q_OBJECT, construímos a implementação do método metaObject(), que cria um objeto que permite por exemplo a listagem das propriedades presentes naquele objeto, bem como a utilização de mecanismos para acessar e alterar estas propriedades. Existem outros mecanismos de reflexão voltados para a listagem e chamada de métodos também.

                    Porém para utilizar este mecanismo de propriedades, sua classe deve herdar de QObject, o que torna impossível o objeto ser passado como cópia para métodos devido a restrições impostas pela própria implementação de QObject.

                    Dê uma olhada em:
                    http://qt-project.org/doc/qt-5/metaobjects.html#meta-object-system
                    http://qt-project.org/doc/qt-5/properties.html

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      micdoug
                      wrote on last edited by
                      #10

                      Outra coisa que esqueci de falar, o QtCreator tem um atalho para criar métodos get e set. Crie uma variável dentro de uma seção private, coloque o cursor de edição em cima do nome da variável e pressione alt+enter. Dentre as opções que aparecem, aparece uma para criar os gets e sets.

                      1 Reply Last reply
                      0
                      • D Offline
                        D Offline
                        Daniel Alves
                        wrote on last edited by Daniel Alves
                        #11

                        Bom,
                        eu estava utilizando o Q_PROPERTY e escrevia os gets e sets todos na mão como ele falou e ainda fazia a verificação para evitar o "binding loop", mas depois de um tempo eu percebi que não era necessário, era preciso apenas duas funções Q_INVOKABLE uma para ler e outra para escrever passando o nome do QSqlField, uma vez que um QSqlField guarda um valor QVariant a função de leitura retorna um QVariant para o campo na interface QML, e quando atualiza o valor no QSqlRecord envia um QVariant e tudo ficou muito mais simples e mais rápido. Foi possível excluir vários arquivos fontes apenas com gets e sets, criei apenas um RecordBase herdando QSqlRecord criei o set e o get, e um ModelBase que conecta com banco e lê os campos e os tipos de dados de cada Tabela, e ao selecionar a tabela para cada registro no banco é criado um RecordBase com os tipos corretos que o modelo fornece, fazer a ligação com os campos da interface QML é muito fácil.
                        É uma ideia alternativa para o Q_PROPERTY que você pode implementar.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved