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

 
Реter Konow:

)))那么,我为什么要发起这个话题呢?)我现在要去学习OOP。


这就是你的方式的优势--从实践到理论。我也做过这种方式。我的直觉曾经在很长一段时间内抵制OOP范式,因为我开始编程时,它并不存在于野外。但现在我明白,这是编程中最有价值的发明。有时在我看来,如果AOP至今没有被发明,我就会自己发明它:))
你,彼得,会喜欢它的,当你意识到OOP的可怕之处以及它所带来的机会时,你会感到很高兴。我向你保证:))。而且,在OOP中没有什么复杂和纠结的东西,特别是对于有编程经验的你来说。而在我看来,在你的案例中,Metacvots的文件 甚至可能足以让你了解它的真相。外面有很多文献。
标签 Konow:

但尼古拉,我还是不明白我在问什么--在CCcanvas类中,是否有可能为框架的渐变线设置特定的颜色?看了你的例子,你可能认为有...如果是这样,你能画出与我的例子类似的东西吗?

好的,好的。虽然这不是这个主题,但我会试着澄清一些对知识渊博的程序员来说很明显,但对第一次接触Canvas的程序员来说并不明显的事情。
那么,什么是Canvas。从英语翻译过来就是一块画布。它只是在一个窗口内的屏幕的任何区域,然后将其连接在一起。它的主要特点是它的尺寸(宽度和高度)。而事实上,它是一个 由uint(4字节)类型的点组成的一维 数组,大小为Width*Height。在 CCanvas 类的实现中,这个数组被称为 m_pixels,默认情况下它是私有的(这意味着它只能在类内部访问),但我个人总是把它变成公共的(不仅在类内部,而且在用户应用程序中也可以访问),因为我想直接操作数据数组。这个画布上的每个点可以采取任何颜色类型的值(也是像uint一样的4个字节,保留一个字节),这意味着任何RGB颜色的一个点。每种颜色(红、绿或蓝)对应一个字节(256个值),所以总共有256*256*256=16,777,216种RGB颜色。

要在X,Y坐标上放置一个红点,X可以从0到(Width-1),Y从0到(Height-1),只要给数组m_pixels中编号为(Y*Width+X)的单元格分配一个红色值。

m_pixels[Y*Width+X]=clrRed;

或什么是相同的。

m_pixels[Y*Width+X] = 0x0000FF; // 0x00FF00 зеленый, - 0xFF0000 - синий, 0x00FFFF - желтый и т.д.

这就是全部!!!。
你现在甚至不能使用CCanvas类的内置函数(这当然很傻,因为那里有很多有用的东西)。如果你能在屏幕上的任何地方、任何颜色放上一个点--你就上帝你想要的东西,并把它画出来:按钮、图形、创建你自己的GDI,等等等等。

如果有人认为kanvas很慢,那他们就错了。Kanvas的速度快得令人难以置信,这是开发团队的功劳。我也曾多次用C++编写的Dll库测试过kanvas的绘制速度。现在经过去年的更新,MT5上的画布几乎和你在Visual Studio中用C++编写的一样快。它只是慢了10-15%。而且别忘了--Windows是用C++编写的,它都是Canvas。这就是MT5的魅力和承诺,它的MQL5!!!。无论是Java还是C#,都无法夸耀这样的速度,就像有些人在这个主题中写的那样。

开发人员最近引入了一个新的属性CHART_SHOW来禁止渲染图形,这并非没有道理。
我将用一个脚本的例子来证明这一点。

//+------------------------------------------------------------------+
//|                                                  CleanScreen.mq5 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

// Внимание !!! В классе CCanvas массив m_pixels должен быть определен как public
#include <Canvas\Canvas.mqh>

void OnStart()
  {
   ChartSetInteger(0,CHART_SHOW,false); // очищаем экран от всего
   int Width =(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);  // получаем Ширину экрана
   int Height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS); // получаем Высоту экрана

   CCanvas C;   // создаем объект Canvas
   if(!C.CreateBitmapLabel(0,0,"CleanScreen",0,0,Width,Height,COLOR_FORMAT_XRGB_NOALPHA)) // Создаем холст на весь экран
      Print("Error creating canvas: ",GetLastError());

// Теперь что-нибудь нарисуем на этом чистом экране
// например красную точку в центре экрана
   int X=Width/2;
   int Y=Height/2;
   C.m_pixels[Y*Width+X]=0xFF0000; // красный
                                   // или нарисуем окружность в центре с радиусом 100 по точкам фиолетового цвета
   int r=100;
   int q=(int)ceil(r*M_SQRT1_2);
   int r2=r*r;
   for(int x=0; x<=q; x++)
     {
      int y=(int)round(sqrt(r2-x*x));
      C.m_pixels[(Y+y)*Width+X+x]=0xFF00FF;
      C.m_pixels[(Y+y)*Width+X-x]=0xFF00FF;
      C.m_pixels[(Y-y)*Width+X+x]=0xFF00FF;
      C.m_pixels[(Y-y)*Width+X-x]=0xFF00FF;
      C.m_pixels[(Y+x)*Width+X+y]=0xFF00FF;
      C.m_pixels[(Y+x)*Width+X-y]=0xFF00FF;
      C.m_pixels[(Y-x)*Width+X+y]=0xFF00FF;
      C.m_pixels[(Y-x)*Width+X-y]=0xFF00FF;
     }
// конечно же можно окружность построить проще :) - через встроенную функцию класса CCanvas:
   C.Circle(X,Y,r+20,0xFFFF00); // желтого цвета
   C.Update(); // Теперь выводим это на экран
  }

这个脚本的操作。


屏幕被清空了,但对报价的访问仍然存在,我们可以用这块空白的画布来制作我们自己的图表界面,比如这个带渐变的界面。


Regex Konow

但是尼古拉,我还是没有理解我所问的问题--在CCcanvas类中是否有一个选项可以为框架的渐变线设置特定的颜色?看了你的例子,人们会认为有...如果是这样,你能画出与我的例子类似的东西吗?

颜色是在GButton类里面定义的,甚至还有两个函数用于混合两种颜色和创建一个颜色数组,从一种颜色流向另一种颜色,也就是说,只是用于梯度。这只是一个定义梯度概念的问题。根据我的理解,渐变(或渐变填充)是一种颜色向另一种颜色的平滑流动。在你的例子中,没有梯度,只有4种颜色。在我的例子中,在GButton类里面,形成了4个额外的颜色,颜色的亮度不同,并且为渐变填充形成了一个颜色阵列。这样做正是为了让班级的终端用户生活得更轻松。他为什么要为这些颜色的形成而烦恼呢?
画一些与你的例子类似的东西--这是你的功课,彼得:))来吧,开始理解类,因此是OOP。
好运!
 
Nikolai Semko:

好运!

好的,尼古拉。谢谢你,也祝你好运!
 
Nikolai Semko:

尼古拉,我想在昨天回复你的内容丰富的帖子,但我无法收集我的想法。现在我收集了我的想法,并意识到我需要从我的心出发,而不是从我的头脑中写,否则我不会解释什么。当然,这将是偏离主题的,版主可能会删除它,但仍...

你写的关于OOP的内容很有启发性。我已经开始学习它,认真打算掌握它。然而,在学习的过程中,我不断受到 "既然有捷径,为什么还要走远路 "这类问题的轰炸。我不断地看到简单、简明、清晰的解决问题的方法,就好像有人告诉我:"不!在OOP中这不是一个解决方案。你必须以一种正式的、正规的和高尚的方式来做。"对此,我问自己:"但这怎么可能呢?我不需要这些实体。我为什么要把它们添加到代码中?他们是多余的。我想压缩代码。"我说:"不,这不专业。这是很糟糕的代码。"

我在OOP的问题上争论了很久,试图弄清楚它对我的优势是什么。我想:"如果我不用OOP就能完美地、轻松地解决任务,我为什么要使用它?我为什么要把对我来说简单明了的事情复杂化呢?我应该如何、在哪里以及为什么要把我不需要的东西放到我的代码中?"。后来我决定,我不需要OOP,因为我自己做所有的事情,而且我非常擅长这个。当你自己做所有的事情,并且不期望堵塞任何东西,而且你寻找并找到最有效的解决方案,那么一个自然的问题就出现了:"为什么不呢?看起来,OOP给你带来了舒适和秩序的程序。是的,确实如此。但我有自己的命令。我自己的结构。我自己的实体。我自己的规则。那么我为什么要拒绝它呢?

就像我们的身体拒绝外来组织一样,我也无法与外来思想的产物 "融合"。在任何地方和任何事情上,我都感到被拒绝。对我来说,PLO是一个由别人的思想创造出来的秩序,它没有通过我的功效测试。正是这个测试对我来说是决定性的因素。我意识到,如果我使用OOP,我将是一个比我自己的方式和自己解决所有问题更弱的程序员。我的 "编程优势 "是,我用一种我理解的俄语语言写作,为图形对象使用一个共享的全局内存,我称之为 "内核",并创建大型和复杂的机制,与这个内核一起运作。这是我的方法。

除非有人用这种方法打败我,否则我不会进行OOP编程。直到它做了我所做的事,但甚至更有效。

我问的是kanvas,因为我想了解为什么我的机制在事实上变成了更有效。不是在理论上,不是在代码上的美丽,而是在实践中。

无论如何,感谢尼古拉对我的启发和指导。))

 
Реter Konow:

...

除非有人用这种方法打败我,否则我不会进行OOP编程。

...


这个人可能是你在想象中疯狂战斗的那些风车之一。)
 
Anatoli Kazharski:

这个人一定是你在想象中疯狂对抗的那些风车之一。)
这就对了!巨魔来了......))
 
Реter Konow:
这就对了!巨魔来了......))
平静下来,彼得。他们只是磨坊。他们只是站在那里,执行某种功能,并不试图击败你。尽管谁也不知道在你丰富的想象力中它是如何被想象的。从表面上看,它看起来非常壮观。)
 
Реter Konow:

我绝对不是OOP的粉丝,但是如果你认为自己是一个程序员,你必须知道并且能够清楚地使用它,至少是为了自我教育的需要。

但是否使用它来解决你的应用任务,则取决于你。

 
Anatoli Kazharski:
平静下来,彼得。他们只是磨坊。他们只是站在一旁,履行某种职能,并不试图击败你。虽然谁知道它是如何在你肥沃的想象力中被想象出来的。从表面上看,它看起来非常壮观。)

安纳托利,不管是不是磨坊,我都喜欢战斗和胜利。特别是在我所擅长的方面。我喜欢现场比赛,决斗之类的......这都是进化和自然选择的一部分。所以没关系...只要规则是公平的。

与志同道合的人合作,参与共同的项目,作为团队的一部分工作也很酷。当然,想象力也不能取代现实。如果这是你的意思,我同意。

 
Комбинатор:

...但如果你认为自己是一个程序员,至少为了自我教育,你必须知道并能清楚地使用它。

但是否用它来解决你的应用问题,则取决于你。

人们不能不同意这一点。
 
Реter Konow:

除非有人用这种方法打败我,否则我不会进行OOP编程。直到他们用它做我所做的事,但甚至更有效率。

我问的是kanvas,因为我想了解为什么我的机制在事实上变成了更有效。不是在理论或代码之美,而是在实践中。

无论如何,感谢尼古拉对我的启发和指导。))

如果两个具有同等经验和智力的程序员在创建类似的大型项目 时进行竞争。但第一个只使用函数,而第二个使用函数和类。第二个人肯定会赢。但是,我再说一遍,如果是一个庞大的项目,后者会使它更快,因为会有更少的错误和更多的秩序。而第二个产品将更具有可读性、可维护性,更容易更新和补充。这甚至不是我的imho,这只是一个事实的陈述。用铲子挖洞比用镘刀挖洞更容易。如果你不仅在函数上实现你的机制,也在类上实现你的机制,它将变得更有效率。这是我的看法。

还有,彼得,我快速看了一下你的代码,发现你在最大程度上使用了canvas(虽然不是CCanvas类,但谁在乎呢)。那么为什么有这么多关于画布的问题,为什么我在这里要解释这些事情?:)).