在Canvas上做一个众包项目 - 页 36

 

对话中的任何元素(表单、控件(按钮、列表、图片))都有一些属性。程序化编程没有定义 "属性 "或 "字段 "的概念。在程序性编程中,我们有函数和变量(全局或局部)。但变量是共同的,所以它们不能用来描述每个单独的控制的属性。那么解决方案是什么呢?一个简单的问题--结构!

是的,一个结构可以有对控件必要属性的描述,也可以有嵌套的(最多无穷个)控件阵列。

所有这些东西都储存在一个对话框的阵列中。

我们可以让它更通用:控制描述结构由两个数组组成:属性数组和从属元素数组。一个属性数组是一个属性-值对的结构数组。通过这种方法,每个新的控件可以有任何任意的属性集。但这对处理来说并不方便。更合理的做法是在结构中指定控件的具体属性:尺寸、位置、颜色、框架等等--任何控件需要的一切。

而且该结构还将包含一个控件的像素数组。

当收到一个鼠标事件时,所有的数组都会被循环,以检查光标是否击中一个特定的控件。检查是从最后一个控制点到第一个控制点进行的。

一旦确定哪个控件有光标,那么给定的数组元素将被发送到repaint函数,然后资源数组被更新,图表上的图像被更新。

Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
Документация по MQL5: Константы, перечисления и структуры / Константы объектов / Свойства объектов
  • www.mql5.com
Все объекты, используемые в техническом анализе, имеют привязку на графиках по координатам цены и времени – трендовая линия, каналы, инструменты Фибоначчи и т.д.  Но есть ряд вспомогательных объектов, предназначенных для улучшения интерфейса, которые имеют привязку к видимой всегда части графика (основное окно графика или подокна индикаторов...
 
Реter Konow:

我不知道他发了什么帖子,在GUI事项上做了什么,但在我的线程中,他没有提出任何技术建议,没有解决方案,也没有讨论这个问题。只有空洞的扯皮,指出第三方的解决方案,并敦促不要重新发明轮子。

回到眼前的话题。

就我对标准库的熟悉程度而言(实际上非常少),那里的元素和窗口是由MT对象组成的。也就是说,在我们的背景下--它们不是画在画布上的。当然,它们是被画出来的,但不是在我们的画布上,这使我们无法控制像素颜色,创建表面渐变等。

理论上,我们可以把库的结构,复制并在画布上做一个模拟。在理论上...

问题是,CCanvas本身并不适合在其上制作GUI。为什么?因为Kanvas系统主要用于图形基元。因此,从本质上讲,这个类除了提供基元外,不提供任何东西。GUI原型必须由自己建立。而在这种情况下,这门课是没有必要的。用自己的解决方案来做更方便。毕竟,你可以画一个长方形的标记,而不需要类。就像你可以创建或加载一个画布。这非常简单。因此,我更喜欢我自己的解决方案。

但有人不能没有CCanvas。这就是我不坚持的原因。

CCanvas的问题是,它的GUI严格地与图表窗口相联系。
也就是说,你不能把一个成熟的窗口作为一个终端界面模块。
而且,如果能写出你自己的接口模块,那将是非常酷的。

 
Maxim Kuznetsov:

当然稍有不慎 :-)

我发布了一个Tcl DLL(也就是工具通用语言)的接口,它有Tk图形,可以作为Python/Ruby/等的GUI来共享

我们的目标不是为了得到一个GUI,而是一个漂亮的副产品 :-)

tcl.Eval("button .pressme -text {Hello Peter}; pack .pressme") ;

在我看来很方便,最重要的是很短:-)

我不是在煽动任何人--我了解tcl/tk,我使用它,我分享我的经验(见sourceforge atcl)。

是的,麦克斯,这正是我所说的TCL和你的原型,我们当时正在讨论的。那里的限制是,用户必须在其计算机上安装适当的库。这似乎并不困难,但还是有一定的局限性。

让我们把这个问题留在过去。马克斯,加入我们的讨论。罗曼,也加入进来吧)))。

 

从上面可以理解,结构元素是一个特定的对话框控件,它包含自己的属性,可以包含嵌套的控件。这样一个通用控件的属性集只受限于开发者的想象力。

当然,我们可以避免这种结构,用一个多维数组 来描述控件的属性,但最初并不划算,因为我们需要清楚地记住某些属性的哪个索引被存储。而且阵列不能包含异质数据类型。事实证明,程序化编程中的控制元素的描述只有通过结构才能实现。也就是说,结构元素是一个具体的控件,也就是具有属性的对话框的具体对象。

Документация по MQL5: Основы языка / Переменные
Документация по MQL5: Основы языка / Переменные
  • www.mql5.com
Переменные должны быть объявлены перед их использованием. Для идентификации переменных используются уникальные имена. Описания переменных используются для их определения и объявления типов. Описание не является оператором. Индексом массива может быть только целое число. Допускаются не более чем четырехмерные массивы. Нумерация элементов...
 
Roman:

CCanvas的问题是,它的GUI严格地与图表窗口相联系。
也就是说,你不能把一个成熟的窗口作为一个终端界面模块。
而且,如果能写出你自己的接口模块,那将是非常酷的。

然后会有相反的情况--将界面与图表联系起来。例如,做一个与时间和价格严格挂钩的按钮。

一个独立的GUI可以在短时间内编写出来--包括所有的表格、标签、菜单和口哨。在C#或甚至BASIC中。而在图表内部,对于外部应用来说是一个重大问题。

 
Алексей Барбашин:

对话中的任何元素(表单、控件(按钮、列表、图片))都有一些属性。程序化编程没有定义 "属性 "或 "字段 "的概念。在程序性编程中,我们有函数和变量(全局或局部)。但变量是共同的,所以它们不能用来描述每个单独的控制的属性。那么解决方案是什么呢?一个简单的问题--结构!

是的,一个结构可以有对控件必要属性的描述,也可以有嵌套的(最多无穷个)控件阵列。

所有这些东西都储存在一个对话框的阵列中。

我们可以让它变得更加普遍:控制描述结构由两个数组组成:属性数组和从属元素数组。一个属性数组是一个属性-值对的结构数组。通过这种方法,每个新的控件可以有任何任意的属性集。但这对处理来说并不方便。更合理的做法是在结构中指定控件的具体属性:尺寸、位置、颜色、框架等等--任何控件需要的一切。

而且该结构还将包含一个控件的像素数组。

当收到一个鼠标事件时,所有的数组都会被循环,以检查光标是否击中一个特定的控件。检查是从最后一个控制到第一个控制进行的。

一旦确定哪个控件有光标,那么数组中的元素就会被发送到repaint函数,然后更新资源数组并更新图表上的图片。

1.假设你设计了一个基本控件的简单结构--一个窗口、一个按钮、一个复选框。每一个都是由一组组件组成的--对象。复选框 - 基础、文本、图标。按钮 - 底座、文本、图标,等等。每个元素的每个对象都必须有自己的一套属性。你可以把它们写在一个结构或类中,但在我看来,这并不方便。为什么?- 因为当你把它们放在一个窗口中时,你需要用光标在画布上找到它们。当你移动光标时,它们必须成为焦点。为此,他们的当前坐标必须在一个数组中。而且,如果它们的所有属性(包括当前坐标)都在同一个数组中,那就更方便了。通过这种方式,你可以立即访问画布上作为光标焦点的任何元素的任何属性。循环浏览一个数组的项目也比较容易。

也就是说,在一个循环中遍历一个数组,找到光标碰到的元素是比较容易的。如果这个数组是全局的,那就更方便了。然后,在任何函数中,你可以从中获取必要的信息,改变必要的属性、必要的元素的值。

这是对元素最短和最有效的访问,也是对其最快的处理。这是我的 "核心"。

2.然而,由于知道专业人士追求最大限度地模仿标准OOP的奇思妙想,我并没有提出这项技术。

3. 像素阵列不需要存储在任何地方。它是在必要的时候,根据数组中元素的参数来建立的。例如:你需要重新绘制窗口。我们调用repaint函数。该函数调用元素数组,看到其所有属性,声明像素数组,计算其大小,在循环中连续绘制其对象,调用ResourceCreate()。就这样了。

在光标下抓到的元素会被送到同一个函数中进行重绘。它收到一个通知(重绘标志)和它在项目阵列中的编号。接下来,该函数通过ResourceReadImage()调用所需资源,将其放入像素数组,然后在像素数组内,找到所需元素的区域,并重新绘制其所有对象。 就这样了。

 
Реter Konow:

1.假设你设计了一个基本控件的简单结构--一个窗口、一个按钮、一个复选框。每一个都是由一组构成部分--物体组成的。复选框 - 基础、文本、图标。按钮 - 底座、文本、图标,等等。每个元素的每个对象都必须有自己的一套属性。你可以把它们写在一个结构或类中,但在我看来,这并不方便。为什么? - 因为当你把它们放在一个窗口中时,你需要用光标在画布上找到它们。当你移动光标时,它们必须成为焦点。 为此,它们的当前坐标必须在一个数组中。而且,如果它们的所有属性(包括当前坐标)都在同一个数组中,那就更方便了。通过这种方式,你可以立即访问画布上作为光标焦点的任何元素的任何属性。循环浏览一个数组的项目也比较容易。

也就是说,在一个循环中遍历一个数组,找到光标碰到的元素是比较容易的。如果这个数组是全局的,那就更方便了。然后,在任何函数中,你可以从中获取必要的信息,改变必要的属性、必要的元素的值。

这是对元素最短和最有效的访问,也是对其最快的处理。这是我的 "核心"。

2.然而,由于知道专业人士追求最大限度地模仿标准OOP的奇思妙想,我并没有提出这项技术。

3. 像素阵列不需要存储在任何地方。它是在必要的时候,根据数组中元素的参数来建立的。例如:你需要重新绘制窗口。我们调用repaint函数。该函数调用元素数组,看到其所有属性,声明像素数组,计算其大小,在循环中连续绘制其对象,调用ResourceCreate()。就这样了。

在光标下抓到的元素会被送到同一个函数中进行重绘。它收到一个通知(重绘标志)和它在项目阵列中的编号。接下来,该函数通过ResourceReadImage()调用所需资源,将其放入像素数组,然后在像素数组内,找到所需元素的区域,并重新绘制其所有对象。就这样了。

实际上,不管建筑技术如何,这应该是可行的。但可以有不同的看法。在你的例子中,你在循环中传递一个数组,并确定在那一刻哪个控件有光标。因此,当你定义索引时,你会立即看到找到的项目的属性。但如何在一个大数组中存储不同类型的数据

Документация по MQL5: Основы языка / Типы данных
Документация по MQL5: Основы языка / Типы данных
  • www.mql5.com
Любая программа оперирует данными. Данные могут быть различных типов в зависимости от назначения. Например, для доступа к элементам массива используются данные целочисленного типа. Ценовые данные имеют тип двойной точности с плавающей точкой. Это связано с тем, что в языке MQL5 не предусмотрено специального типа для ценовых данных. Данные...
 
Алексей Барбашин:

事实上,无论建筑技术如何,这都应该发生。你只能以不同的方式来感知它。在你的例子中,你在数组中循环,并确定哪个控件此时有光标。因此,当你定义索引时,你会立即看到找到的项目的属性。但如何在一个大数组中存储不同类型的数据

原则上,有可能对这些类型进行概括。我得出的结论是,如果绝大多数对象的属性都是int类型的,那么就不会发生什么坏事。所有其他(图形对象的属性中几乎没有double)的缩写类型我都为了简化而忽略了。 记忆 "超限 "是如此微不足道,以至于思考它没有意义。当然,我们不能为了专业性而去做这样的亵渎行为)))。但现在是21世纪,我不会受到篝火的威胁)。

我把物体的名称作为数字,并把它们放在物体属性的一般系列中。

我需要不同类型数据的唯一地方是控制参数。在那里,我创建了第二个内核,它存储了参数属性,以及字符串类型的值本身,我可以很容易地将其转换为任何东西(或者说,转换为参数属性中所规定的东西)。

提示:"控制元素参数 "是指设备所管理的参数。
 
Реter Konow:

1.假设你设计了一个基本控件的简单结构--一个窗口、一个按钮、一个复选框。每一个都是由一组构成部分--对象组成的。复选框 - 基础、文本、图标。按钮 - 底座、文本、图标,等等。每个元素的每个对象都必须有自己的一套属性。你可以把它们写在一个结构或类中,但在我看来,这并不方便。为什么?- 因为当你把它们放在一个窗口中时,你需要用光标在画布上找到它们。当你移动光标时,它们必须成为焦点。为此,他们的当前坐标必须在一个数组中。而且,如果它们的所有属性(包括当前坐标)都在同一个数组中,那就更方便了。通过这种方式,你可以立即访问画布上作为光标焦点的任何元素的任何属性。循环浏览一个数组的项目也比较容易。

也就是说,在一个循环中遍历一个数组,找到光标碰到的元素是比较容易的。如果这个数组是全局的,那就更方便了。然后,在任何函数中,你可以从中获取必要的信息,改变必要的属性、必要的元素的值。

这是对元素最短和最有效的访问,也是对其最快的处理。这是我的 "核心"。

2.然而,由于知道专业人士追求最大限度地模仿标准OOP的奇思妙想,我并没有提出这项技术。

3. 像素阵列不需要存储在任何地方。它是在必要的时候,根据数组中元素的参数来建立的。例如:你需要重新绘制窗口。我们调用repaint函数。该函数调用元素数组,看到其所有属性,声明像素数组,计算其大小,在循环中连续绘制其对象,调用ResourceCreate()。就这样了。

在光标下抓到的元素会被送到同一个函数中进行重绘。它收到一个通知(重绘标志)和它在项目阵列中的编号。然后,该函数通过ResourceReadImage()调用所需的资源,将其放入像素数组,并进一步在像素数组中找到所需的元素区域,重新绘制其所有对象。就这样了。

这是对OOP的永恒的否定,正确地跨越了界限。

你是否曾想过它是如何产生的?问题是,许多用过程式写东西而不了解OOP的人都面临着将函数分组的愿望,然后这种愿望发展为将这些函数组合成一个内存区域,并对其进行引用,也就是物理上引用存储在一个变量中的函数区域。然后我们要改变我们选定的一堆函数,而不重复代码(我们得到了继承)。因此,一个最初只熟悉程序化风格的人在一段时间后会问,为什么在mql(指多重继承)中有这么多限制。

一般来说,人们认为一次性教授OOP比较容易,因为如果一个人熟悉了过程式风格,那么就很难再训练了(对大多数 人来说),但也有其他人,因为最初只有过程式风格...上述内容。

ZS 在一般情况下,有一个关于OOP的变种,有点熟悉程序性代码层面的OOP,而真正将OOP发挥到极致。

一个类是对一个内存(表)函数的引用,它可以被重写和扩展,同时保持主阵列+对变量的引用。我忘了还有什么....(如32字节)

对于搜索永恒的问题,我最近将内置的排序功能与Red sort(模板之一)进行了比较,在某些情况下,速度损失了3-6倍(内置的损失=)。

关于GUI,我想有一些标准的方法。

,

 
Alexandr Andreev:

唉,这种对OOP的永恒的否定,就在对面。

你是否曾想过它是如何产生的?事情是这样的,许多用过程式写东西的人,在不了解OOP的情况下,面临着将函数分组的愿望,然后这种愿望发展成将这些函数组合成一个内存区域,并对其进行引用,也就是物理上引用一个存储有函数的区域。然后我们想改变我们选定的一堆函数,而不重复代码(我们得到了继承)。因此,一个最初只熟悉程序化风格的人在一段时间后会问,为什么在mql(指多重继承)中有这么多限制。

一般来说,人们认为一次性教授OOP比较容易,因为如果一个人熟悉了过程式风格,那么就很难再培训了(对大多数人来说),但也有其他人,因为最初只有过程式风格...上述内容。

ZS 在一般情况下,有一个关于OOP的变种,有点熟悉程序性代码层面的OOP,而真正将OOP发挥到极致。

一个类是对一个内存(表)函数的引用,它可以被重写和扩展,同时保持主阵列+对变量的引用。我忘了还有什么....(如32字节)

对于搜索永恒的问题,我最近将内置的排序功能与Red sort(模板之一)进行了比较,在某些情况下,速度损失了3-6倍(内置的损失=)。

关于GUI,我想有一些标准的方法。

,

我对OOP的概念没有任何否定的意思。我自己也是它的信徒。我对标准有一个否定。更准确地说,是无意识地跟随他们)。

除此以外,我支持OOP。但我支持简化的OOP。