Discussão do artigo "Interfaces Gráficas III: Botões Simples e Multifuncionais (Capítulo 1)"

 

Novo artigo Interfaces Gráficas III: Botões Simples e Multifuncionais (Capítulo 1) foi publicado:

Vamos começar a estudos sobre o controle chamado botão. Nós vamos mostrar exemplos de várias classes para a criação de um botão simples, botões com funcionalidades estendidas (botão com ícones/imagens e botão de divisão - "split button") e aqueles que são interconectados (grupos de botões e botão de radio). Além disso, nós vamos apresentar alguns incrementos para as classes existentes afim de ampliar a capacidade dos controles.

Vamos começar com um botão simples. Nós já preparamos uma classe para criar um objeto primitivo de controle do tipo CButton no arquivo Objects.mqh. A CChartObjectButton é a sua classe base, que pode ser utilizada para criar um objeto gráfico do tipo OBJ_BUTTON. As propriedades desse objeto já implicam em dois estados - ligado (pressionado) e desligado (solto). A sua representação gráfica também pode ter duas opções, ela depende se a exibição do quadro do objeto está ativada ou não. Em ambos os modos, a cor do botão é ligeiramente mais escura quando ele está pressionado do que em seu estado solto

Este objeto pode ser ligado ao gráfico manualmente a partir do menu principal: Inserir -> Objetos -> Objetos gráficos -> Botão. Os parâmetros também podem ser alterados manualmente a partir da janela de configurações do objeto gráfico:

Fig. 1. A janela de configurações do objeto gráfico botão.

Fig. 1. A janela de configurações do objeto gráfico botão.

 

Autor: Anatoli Kazharski

 
Com base em minha experiência pessoal, posso dizer que tornar as janelas "flexíveis" (ou seja, dinâmicas) não é uma tarefa fácil. Se falarmos de uma forma simples de janela, sem nenhum objeto, é definitivamente mais fácil torná-la extensível, mas aqui é necessário todo um conceito de interação entre o usuário e a janela. Uma janela padrão do Windows tem pelo menos 8 alças, que permitem que você altere convenientemente o tamanho da janela em qualquer direção. Veja, por exemplo, a janela "Alerta". Não é fácil implementar esse comportamento de janela. Agora vamos voltar a uma janela comum que contém um grande número de vários objetos. Você percebe que os objetos estão em vários tipos de relacionamentos entre si. Isso significa que, quando você redimensiona a janela, seus locais (ou tamanhos) mudam de forma diferente. Algumas figuras, por exemplo, se movem para trás da caneta, enquanto outras permanecem no lugar. Alguns campos de entrada mudam de comprimento, outros, ao contrário, mantêm o mesmo tamanho. Portanto, acho que é um pouco precipitado dizer que essa tarefa é uma das mais fáceis de resolver).
 
Реter Konow:
Com base em minha experiência pessoal, posso dizer que tornar as janelas "flexíveis" (ou seja, dinâmicas) não é uma tarefa fácil. Se falarmos de uma forma simples de janela, sem nenhum objeto, é definitivamente mais fácil torná-la extensível, mas aqui é necessário todo um conceito de interação entre o usuário e a janela. Uma janela padrão do Windows tem pelo menos 8 alças, cuja utilização permite que você altere convenientemente o tamanho da janela em qualquer direção.

Pela minha experiência, sei como implementar isso, e algo semelhante já foi implementado em um dos controles planejados para publicação. Um exemplo estará em um dos próximos artigos desta série.

Veja, por exemplo, a janela"Alerta". Não é fácil implementar esse comportamento de janela.

O que você acha que é tão difícil? Essa janela tem apenas uma tabela com três colunas e um botão "Fechar". Quando você redimensiona a janela horizontalmente, a largura das colunas muda proporcionalmente à largura da janela atual. Para mim, é melhor tornar a largura das colunas fixa. E quando a largura da janela for alterada, deixe aparecer uma barra de rolagem horizontal. De qualquer forma, tudo isso está dentro da classe de um elemento de interface específico e nada impede que você crie esse elemento e apenas o conecte ao mecanismo da biblioteca.

No 18º artigo da série, serão publicadas três classes de tabelas com barras de rolagem horizontais e verticais. Na implementação atual, elas não são "emborrachadas", mas, se você realmente precisar, criarei esse recurso na segunda versão da biblioteca mais tarde.

Agora vamos voltar a uma janela normal que contém um grande número de diferentes tipos de objetos. Você percebe que os objetos estão em vários tipos de relacionamentos uns com os outros. Isso significa que, quando você redimensiona a janela, seus locais (ou tamanhos) mudam de forma diferente. Algumas figuras, por exemplo, se movem para trás da caneta, enquanto outras permanecem no lugar. Alguns campos de entrada mudam de comprimento, enquanto outros, ao contrário, mantêm o mesmo tamanho. Portanto, dizer que essa tarefa é uma das mais fáceis de resolver é um pouco precipitado.)

Ela é resolvida com a adição de métodos às classes, com a ajuda dos quais você pode posicionar elementos e alterar seus tamanhos em relação ao tamanho da janela. No momento, todas essas são tarefas menores que podem ser resolvidas depois que a primeira versão da biblioteca for publicada.

 
Veja bem, a dificuldade não está em copiar uma janela específica e seu comportamento, mas em criar um sistema que gerencie as janelas de forma que você possa implementar qualquer tipo de mapeamento de objetos entre si e os identificadores de janela. Isso lhe dará grandes oportunidades, mas, repito mais uma vez, a OOP não permitirá que você a implemente de forma eficiente. Você terá que escrever muito código. Aposto que, ao comparar meus resultados com os seus, a vantagem não estará do seu lado.)

Entretanto, quero levantar uma questão sobre a diferença que existe entre os painéis oferecidos por muitos desenvolvedores no mercado e a interface. Por que, apesar de sua aparência semelhante à interface clássica (embora nem todos eles), eles não são percebidos como uma interface completa? Como se diferenciam dela? Por que a semelhança externa das janelas e dos controles com os da interface normal não é suficiente? Em que ponto um painel pode ser "reconhecido" como uma interface?




Vou dar minha opinião:

1. A interface padroniza as formas das janelas e dos objetos, bem como seu comportamento em vários eventos (reações às ações do usuário).
Há um método padrão de vincular um objeto gráfico a seu parâmetro e a uma função, uma classificação clara de janelas, objetos e eventos. Essa padronização
está completamente ausente nos painéis.




2- A interface tem um conjunto incomensuravelmente grande de possibilidades de interação do usuário com o aplicativo. Ela permite que o usuário altere facilmente sua aparência,
adotando o tamanho ou a cor que ele precisa. Por assim dizer, ela se "adapta" aos requisitos do usuário.





3. Devido às suas vantagens gráficas, a interface permite exibir nas janelas uma quantidade muito maior de informações do que a exibida pelos painéis.





Sem dúvida, você já deu o primeiro passo para a criação de uma interface. Na sua biblioteca, você padroniza os parâmetros de janelas e controles, deixando que outros substituam propriedades específicas dentro de limites razoáveis. A próxima etapa é ampliar as possibilidades de interação do usuário com a interface. E aqui há muitos problemas (como alterar o tamanho das janelas), sem resolver os quais sua biblioteca corre o risco de continuar sendo apenas uma forma de padronização de painéis para a nova geração de desenvolvedores. Bem, e a última etapa no caminho para a interface é a criação de métodos de interação das janelas com as informações processadas pelo aplicativo, mas em um volume muito maior do que pode ser feito pelos painéis.




Ficarei feliz em ouvir objeções. :)
 

Реter Konow: 

1. Veja bem, a dificuldade não está em copiar uma janela específica e seu comportamento, mas em criar um sistema que gerencie as janelas de forma que você possa implementar qualquer tipo de vínculo entre objetos e alças de janela.

2 Isso lhe dará grandes oportunidades, mas, mais uma vez, a OOP não permitirá que você a implemente de forma eficaz.

3. Você terá que escrever muito código.

4. Aposto que, ao comparar meus resultados com os seus, a vantagem não estará do seu lado).

1. Não entendo, de que implementação estamos falando? Você já tem e terá mais oportunidades, à medida que o restante dos artigos da série for publicado, de fazer uma comparação completa com seus desenvolvimentos. E com o que eu deveria compará-la? ))

2) A OOP lhe dá a oportunidade de gerenciar tudo isso de forma eficaz. Ou expresse sua opinião de forma mais detalhada. De preferência, em alguns exemplos concretos com um breve código que mostre esse ou aquele problema.

3. não tenho medo da complexidade dessa ou daquela tarefa e não importa a quantidade de código que preciso escrever para ela.

4. Não entendo de que vantagem você está falando? Eu não tinha planos de obter nenhuma vantagem sobre você. ))

Retag Konow:

No entanto, quero levantar uma questão sobre a diferença que existe entre os painéis oferecidos por muitos desenvolvedores no mercado e a interface. Por que, apesar de sua aparência semelhante à interface clássica (embora nem todos), eles não são vistos como uma interface completa? Como se diferenciam dela? Por que a semelhança externa das janelas e dos controles com os da interface normal não é suficiente? Em que ponto um painel pode ser "reconhecido" como uma interface?

Darei minha opinião:

...

Sem dúvida, você deu o primeiro passo no caminho para criar uma interface. Na sua biblioteca, você padroniza os parâmetros de janelas e controles, deixando a possibilidade de outros substituírem propriedades específicas dentro de limites razoáveis. A próxima etapa é ampliar as possibilidades de interação do usuário com a interface. E aqui há muitas tarefas (como redimensionar janelas), sem as quais sua biblioteca corre o risco de continuar sendo apenas uma forma de padronização de painéis para a nova geração de desenvolvedores.

Quanto à primeira e à segunda etapas, aguarde até que todos os artigos da série sejam publicados. No momento, apenas 10 artigos foram publicados. Haverá mais de 25 no total.

Retag Konow:

Bem, a última etapa no caminho para a interface é criar métodos para que as janelas interajam com as informações processadas pelo aplicativo, mas em um volume muito maior do que os painéis podem realizar.

Se entendi corretamente, já tenho esses exemplos. Isso poderia incluir classes de tabela para armazenar, recuperar e exibir grandes quantidades de dados.

 
Vou tentar formular a tarefa de criar mapeamentos de objetos e janelas com mais clareza.

Vamos supor que você tenha criado uma janela na qual colocou uma tabela. Acontece que a tabela era muito grande (digamos que seja uma tabela de indicadores estatísticos do histórico comercial). Você coloca uma barra de rolagem vertical na janela (ou ela aparece automaticamente). Mas isso não é suficiente. Você quer que o usuário possa redimensionar a janela para que possa ver apenas a parte da tabela de que precisa. Se ele usar a rolagem, ainda verá mais do que o necessário. Conclusão - você precisa redimensionar a janela. Ajuste seu campo de visão ao tamanho da área importante.

Agora vamos imaginar que, além da tabela, a janela contém vários objetos estáticos importantes (como o ícone de ajuda, o ícone de configurações ou os botões de zoom da janela...). Ao redimensionar a janela (se você mover a alça direita da janela para diminuí-la), esses objetos terão de ficar fora da janela, a menos que se movam na direção certa. Entretanto, se você mover a alça esquerda da janela, esses objetos permanecerão estacionários. Você pode dizer que vinculou determinados objetos à alça direita da janela e que eles só se moverão com ela.

Entretanto, alguns objetos podem ser vinculados a vários outros objetos ao mesmo tempo e a todos eles de forma diferente. Por exemplo, você está cansado de calcular e prescrever coordenadas para cada objeto separadamente. Você só quer encaixá-lo em outro objeto que já esteja definido, na parte superior, inferior, esquerda ou direita. Você cria uma ligação de um objeto a outro e, se o primeiro objeto se mover, o segundo se moverá depois dele.

Infelizmente, não faz sentido mostrar partes do código, pois os comentários a elas excederão várias vezes o tamanho desse código. Você simplesmente não está familiarizado com meu método de programação e meu código não explicará nada, mas o levará a um beco sem saída.

Só posso dizer que tudo o que escrevi foi implementado e funciona perfeitamente bem. Em breve, publicarei mais capturas de tela e vídeos.
Quanto à vantagem, é apenas uma brincadeira. :D
 
Реter Konow:

Vou tentar formular a tarefa de criar mapeamentos de objetos e janelas com mais clareza.

Vamos supor que você tenha criado uma janela na qual colocou uma tabela. Acontece que a tabela era muito grande (digamos que seja uma tabela de indicadores estatísticos do histórico comercial). Você colocou uma barra de rolagem vertical na janela (ou ela aparece automaticamente). Mas isso não é suficiente. Você quer que o usuário possa redimensionar a janela para que possa ver apenas a parte da tabela de que precisa. Se ele usar a rolagem, ainda verá mais do que o necessário. Conclusão - você precisa redimensionar a janela. Ajuste seu campo de visão ao tamanho da área importante.


Agora vamos imaginar que, além da tabela, a janela contém vários objetos estáticos importantes (como o ícone de ajuda, o ícone de configurações ou os botões de zoom da janela...). Ao redimensionar a janela (se você mover a alça direita da janela para diminuí-la), esses objetos terão de ficar fora da janela, a menos que se movam na direção certa. Entretanto, se você mover a alça esquerda da janela, esses objetos permanecerão parados. Você pode dizer que vinculou determinados objetos à alça direita da janela e que eles só se moverão com ela.


Entretanto, alguns objetos podem ser vinculados a vários outros objetos ao mesmo tempo e a todos eles de forma diferente. Por exemplo, você está cansado de calcular e prescrever coordenadas para cada objeto separadamente. Você só quer encaixá-lo em outro objeto que já esteja definido, na parte superior, inferior, esquerda ou direita. Você cria uma ligação de um objeto a outro e, se o primeiro objeto se mover, o segundo se moverá depois dele.


Todas as tarefas acima são bastante simples. Não vejo nenhum problema com isso. Ou seja, seria possível adicionar esses recursos em qualquer estágio do desenvolvimento do projeto.

Retag Konow:

Infelizmente, não faz sentido mostrar trechos de código, pois os comentários a eles excederão várias vezes o tamanho desse código. Você simplesmente não está familiarizado com meu método de programação, e meu código não lhe explicará nada, mas o levará a um beco sem saída. Só posso dizer que tudo o que escrevi foi implementado e funciona perfeitamente bem. Em breve, publicarei mais capturas de tela e vídeos.

Então, não haverá exemplos que expliquem por que a OOP limita suas habilidades de programação? Você pode apenas desenhar um esquema de que é impossível implementar tal projeto usando OOP, mas é possível usando seus métodos. Isso será suficiente.

E o que devemos fazer com suas capturas de tela e vídeos? Os recursos MQL permitem que você implemente interfaces gráficas de qualquer complexidade. Para exemplos do que pode ser uma interface gráfica, é melhor se concentrar nas interfaces gráficas dos sistemas operacionais. Ou seja, algo que seja feito com qualidade suficiente (erros e falhas também ocorrem no Windows) e que possa ser testado por você mesmo, e não apenas visto em um vídeo.

Se seu plano é vender sua biblioteca, pelo menos publique seus exemplos de DEMO gratuitos no mercado para que possamos testá-los e tirar conclusões. E também escreva um artigo em que possamos entender como usar sua biblioteca para criar GUIs em nossos aplicativos MQL. Apenas capturas de tela e vídeos estão longe de ser suficientes para a avaliação. ;)

 
Anatoly, você é um desenvolvedor. Eu também sou desenvolvedor. Nós dois desenvolvemos interface para programas nas plataformas MT4/MT5. Essa disputa sobre a abordagem de programação pode ocorrer entre pessoas que são "profundas" no assunto. Não poderei explicar todas as nuances, problemas ou vantagens dessa ou daquela abordagem para pessoas que não estiveram envolvidas no desenvolvimento de interfaces independentes.

Não nego que, usando OOP, você pode resolver as tarefas acima, mas essa solução será muito complicada. Se você discorda e continua dizendo que não vê nenhum problema nisso e que são tarefas bastante simples, sugiro que prove isso na prática.

Minhas capturas de tela e vídeos são apenas uma prova de minhas palavras sobre a solução do problema mencionado acima. Eu iria fornecê-los a você.

Quanto ao esquema ou a outras provas de eficiência, responderei de forma simples: todo o meu programa com a interface pesa 250 kilobytes, sem incluir o kernel. O kernel não é um código de programa e é carregado no programa no estágio de inicialização. Esse fato e mais o vídeo demonstrando os recursos da minha interface serão a prova da eficiência da minha abordagem.

Estou esperando que você prove a eficácia de sua abordagem da mesma forma. Se, é claro, tiver certeza disso))

P.S. Não busco nenhum outro objetivo além de estabelecer a verdade.
 
Observação: Considero o tamanho pequeno do programa uma vantagem.
 
Реter Konow:
...

P.S. Não busco nenhum outro objetivo além de estabelecer a verdade.

A verdade é que, no momento, meus artigos (não os seus) são publicados com uma descrição detalhada da biblioteca, que é de fato fornecida gratuitamente a toda a comunidade MQL. Ao contrário de você, essa é a prova na prática.

Mas você só quer mostrar algumas fotos e vídeos, então começou uma conversa sobre nada, enquanto inventava algum outro argumento. Quando você publicar o código, continuaremos. Enquanto isso, continuarei trabalhando nos outros artigos desta série para que você possa fazer uma comparação mais completa mais tarde.

Há pelo menos mais 15 artigos pela frente. Portanto, você está muito adiantado para começar a comparar.

Retag Konow:
Observação: vejo o tamanho pequeno do programa como uma vantagem.

Não é engraçado. Provavelmente tantos recursos quanto códigos. Se você pudesse remover todos os comentários ou até mesmo ofuscá-los, ele seria ainda menor.

 
Anatoli Kazharski:

A verdade é que, no momento, meus artigos (não os seus) são publicados com uma descrição detalhada da biblioteca, que é de fato fornecida gratuitamente a toda a comunidade MQL. Ao contrário de você, essa é a evidência na prática.

Eu não queria escrever nada... mas

  • Anatoly, você não é muito modesto com relação à "verdade" e à "prova".
  • Lembre-se do diálogo: "... como é difícil ler seus artigos..." a resposta do autor: "e você sabe como é difícil escrevê-los?". Anatoly, obrigado pelo seu trabalho, mas tenho uma pergunta: para quem você publica artigos "gratuitamente"? Isso não é interessante para pessoas avançadas, e para iniciantes é incompreensível. Há muitos códigos nos quais você não quer escolher e sistematizar o que escreveu.
  • Anatoly, seu leitor faz perguntas sobre seu artigo e, aparentemente, você não está satisfeito com ele. Além disso, a opinião dele não lhe interessa em nada e até o irrita. Então, o que o leva a escrever artigos?
  • Os autores precisam de críticas para mudar para melhor.

Com todo o respeito a você, esteja mais próximo de seus leitores e não se empolgue com meia volta na hora.