Galeria de UIs escritas em MQL - página 54

 
Há algo errado, Peter.
Um atraso de um segundo é um atraso proibitivo. A formação da interface mais complicada para toda a janela não deve exceder 50 milissegundos.
Parece mesmo que a lógica de renderização está sobrecarregada com as funções Update (na verdade, ChartRedraw).
Para verificar essa suposição, coloque um contador estático na função Update da classe CCanvas (se você a usar) e imprima esse contador, por exemplo, quando count%100 == 0.
 

Também tenho uma tela em tela cheia que é redesenhada completamente a cada alteração, mas isso não leva mais do que 50 ms....

O mais caro é desenhar o texto. Portanto, para não usar TextOut todas as vezes, eu os armazeno em matrizes. O resultado é muito mais rápido.

 

O principal desafio agora é dar ao usuário controle programático sobre os controles da interface.

Tecnicamente, a tarefa não é difícil, pois na união simbiótica do programa do usuário e do mecanismo, o núcleo gráfico é visível em nível global para os algoritmos de ambas as partes. O problema é que o usuário não sabe como trabalhar com o kernel. Ele não conhece e não entende os princípios do gerenciamento de elementos. Portanto, é necessário fornecer wrappers familiares - funções por meio das quais ele pode acessar o kernel e alterar valores.

Mas há uma nuance. Os nomes das funções são muito longos. Afinal de contas, cada invólucro funcional de um elemento interativo deve incluir os nomes do elemento e da janela. Isso é necessário para a orientação entre os nomes. Caso contrário, o usuário ficará facilmente confuso e não entenderá seus envoltórios de função. Além disso, os nomes podem coincidir, o que não é nada bom. Portanto, você precisa gerar nomes a partir de dois componentes: o nome do elemento e o nome da janela. Assim, não há confusão, mas os nomes dos wrappers ficam muito longos. Especialmente com o lado dos parâmetros passados. Além disso, você precisa adicionar prefixos às funções para localizá-las rapidamente por meio do intellisense. Isso permite uma filtragem eficiente da amostra pop-up. Prático. MAS LONGO!

E não é só isso. O problema são os parâmetros que estão sendo passados. A opção é escrever wrappers para cada get/set-properties predefinido de elementos e janelas, ou cada wrapper aceita a lista completa de parâmetros de uma chamada do usuário. Isso é extremamente inconveniente. E, o mais importante, é difícil de explicar.


Há uma saída e ela é simples. E aqui está o que ela é: um grupo de propriedades abstratas. Variáveis globais simultaneamente visíveis do lado do programa do usuário e do mecanismo.

Como isso funcionará:

1. Todos os wrappers de elementos e janelas se dirigirão à função central e passarão seus índices. Ela os usará para determinar o elemento/janela de destino da chamada.

2. Após essa chamada, o usuário definirá o conjunto selecionado de propriedades abstratas com os valores necessários.

3. Chame a função central e passe a palavra c.word "Set".

4. A central definirá os valores das propriedades abstratas de suas variáveis globais para as propriedades de destino do elemento ou da janela específica.

5. Ele atualizará o elemento/janela e redefinirá as propriedades abstratas para zero.

Isso é tudo.

Em minha opinião, uma solução simples e eficiente que fornecerá

a) Acesso fácil às propriedades de quaisquer elementos e janelas, sem passar parâmetros para uma função que exige consistência rigorosa. (E mais: limitação do número de parâmetros passados. E a chamada acaba sendo longa e ilegível).

c) Combinação livre de um conjunto de propriedades de elementos e janelas ao definir/receber valores em qualquer lugar do programa.


Se alguém vir desvantagens, fale. Seria bom coordenar essa questão antes do lançamento.

 
Nikolai Semko classe CCanvas (se você a usar) e imprima esse contador, por exemplo, quando count%100 == 0.

Nicholas, vale a pena considerar que estamos falando de várias janelas da GUI. Na última versão, havia 17 delas, cada uma com centenas de elementos. E cada elemento é complexo. Ele consiste em um conjunto de partes. Cada detalhe é uma seção da tela pela qual você precisa passar e no lugar certo para preencher com os valores necessários.

Se considerarmos o número médio de 10 janelas (Papkov, eu me lembro, encomendou uma interface de 11 janelas) e imaginarmos que cada uma delas tem um conjunto de elementos ou uma tabela, fica claro por que a renderização completa de toda a interface leva tanto tempo. Deixe-me lembrá-lo de que na interface há ícones, sombras, gradiente de superfície, vários quadros.... então, no total, o desenho completo de TODA a interface levará pelo menos 500 ms. Não há nada que você possa fazer quanto a isso.

Pode ser mais rápido se você reduzir o número de janelas ou simplificar os gráficos.

Com relação ao redesenho, quase não tenho chamadas ChartRedraw() puras. O sinalizador _ChartRedraw é usado em todos os lugares. Quando esse sinalizador é definido, a função ChartRedraw() é chamada na próxima iteração do cronômetro, após 25 ms. Ou seja, uma vez. Dessa forma, evito redesenhos desnecessários. Somente em casos raros, faço uma chamada direta para ChartRedraw().

 
Andrey Barinov #:

A tela de tela cheia também é redesenhada completamente toda vez que eu mudo, mas isso não leva mais de 50 ms...

O mais caro é desenhar o texto. Portanto, para não usar TextOut toda vez, eu os armazeno em matrizes. O resultado é muito mais rápido.

Bem, a aritmética simples funciona aqui: a soma das áreas de 10 a 17 janelas é muito maior do que a tela inteira. Concordo. Além do desenho adicional secundário necessário para criar sombras, ícones, quadros....

E sobre o TextOut, vou verificar e escrever. Ideia interessante.

 

Realizei um teste:

Entrei no arquivo Demo project 1.mqh e configurei todas as janelas com o sinalizador OOI. (abertura na inicialização).

No total, 15 janelas de diferentes tamanhos e conteúdos. 2 janelas com barras de rolagem e tabelas (portanto, a tela está parcialmente oculta e, na verdade, é de 2 a 3 vezes maior. O comprimento total pode ser avaliado pela proporção entre o controle deslizante e a barra de rolagem). Área total de desenho(mínimo) 2000*1000 pixels. Mas acho que é mais do que isso. Total de 1158 partes desenhadas (verificado após a impressão do núcleo). Tempo de desenho completo de todas as telas do zero de 1600 a 1900 ms.

Mais uma vez, preste atenção à quantidade de detalhes que tiveram de ser desenhados. Sombras, ícones, gradientes, quadros, textos.


O tempo de desenho está na captura de tela:


 
Pode haver uma maneira de acelerar o desenho. Remova a base inferior das plataformas das janelas. Essas são telas grandes atrás da parte frontal onde os elementos estão localizados. Se você as remover, o desenho será duas vezes mais rápido. Terei que pensar sobre isso.
 
É possível desenhar determinadas janelas somente quando elas estiverem abertas? É raro ter uma dúzia de janelas abertas ao mesmo tempo. Não há necessidade de fazer isso.
 
hini #:
Posso desenhar determinadas janelas somente quando elas estiverem abertas? É raro ter dezenas de janelas abertas ao mesmo tempo. Não há necessidade disso.

Essa é a única coisa que acontece, acredite em mim. Estou falando apenas do primeiro desenho de todas as janelas da interface ao mesmo tempo. O primeiro desenho é o que leva mais tempo. E, depois disso, todas as imagens já estão salvas e recuperadas da memória, se necessário. Com uma chamada, elas são anexadas às telas em poucos milissegundos. Isso não é um problema. Você só quer comprimir o tempo do primeiro desenho.

 
Реter Konow #:
Pode haver uma maneira de acelerar o desenho. Remova a base inferior das plataformas das janelas. Essas são telas grandes atrás da parte frontal onde os elementos estão localizados. Se você as remover, o desenho será duas vezes mais rápido. Terei que pensar sobre isso.

Esta é a tela de que estou falando:

1. a parte da frente, onde os elementos estão localizados:


2. a parte de trás, onde estão localizados os botões da janela (cruz, minimizador), o ícone e o texto do nome. No entanto, a janela inteira está colorida de verde e foi gasto tempo nela. Porém, o usuário vê apenas os quadros e o cabeçalho da janela. Acontece que, nesse local, o desenho foi feito em vão: