起因是怎么回事呢,就是我呀,最近在学算法,学到了图那一部分了,就面临一个问题,数据结构不好构造,也就会造成自己写的算法就不好测试,算法的正确性也就不可观啦,我也有尝试自己写一个随机生成一个图的算法,也确实写完了,下面是我写的乱生成图的代码,我也就不解释了,有很多的缺点,而且生成的图也不好(好像是生成的图,没有环,不nice),而且具体的数据结构就自己不能很好的掌握,不能看出来图的结构。
void makeGraph(Graph &graph,int n)
{
for(int i = 0; i < n; i++)
graph.node[i] = new Node(i);
Set MySet(graph.node);
int x = 1000;
while(--x > 0)
{
int node1 = rand() % n;
int node2 = rand() % n;
int weight = rand() % 1000 + 10;
while(node1 == node2)
node1 = rand() % n;
if(!MySet.isSameSet(graph.node[node1],graph.node[node2]))
{
Edge *temp = new Edge(weight,graph.node[node1],graph.node[node2]);
graph.edge.insert(temp);
AddEdge(temp);
MySet.Union(graph.node[node1],graph.node[node2]);
}
}
}
那我是能将就的人吗,不可能,就想着是否可以可视化构建一个图呢?我虽不是大佬,但是写点小玩意还是可以的吧。ok,正好呢,我昨天给我导师汇报了一下自己的周报,老师也没搭理我(可能是在准备过年吧),所以,今天下午我就闲下来了(我一般把下午的时间交给我导师给我布置的任务,老师也没找我,我也就不想继续搞老师的东西了),我就准备搞一下这个东西了。很好,我们步入正题。
既然要可视化,那必然用QT啊,主要是其他的我也不会,就略懂QT,那就它了,这个美丽的框架。人啊,如果想要做某件事,怎么做,一般想到这件事的时候,脑子里就会有一个简单的想法,也许它不是很好,甚至有点差,但是总会把他尽力的完成,除非真的完不成,对于我来说是这样的,(我去刷leetcode的时候,基本上看到一个题,第一个想法就是我要做的,除非最后发现是完完全全的错的,否则我不会改变的)。所以呢,我的基本构思就是,利用QT实现一个界面,鼠标点击一下就在界面上画出一个点,生成足够的点以后,我再点击两个已经画出来的点会让我设置一条边,最后都设置完之后就会再这上面进行跑一些图算法。现在我还没有办法给你们展示最后的效果图,因为我没有做完,准备打持久战。没关系啊,好事多磨吗,一蹴而就的化,我可能会没有耐心。
我们要实现在界面上画点的操作,怎么实现呢,先去看看QT有没有现成的画点的api。我去百度搜了一下,没有找到画点的,但是找到了画圆圈的(我稍加思索发现,我要找的是圆圈,而不应该是点,因为我要在圆圈里面画出数字,来表示节点的标识。所以啊,大家在寻找一些东西的时候(everything),要看看自己身边是不是有,自己到底是需要什么,自己身边的能不能满足,是不是自己身边的更好。)。
我们已经找到画圈圈的接口了,那我们就要实现上面提到的一个功能了,在圈圈里实现标识的画出。原本呢,我就寻思,直接利用qt的接口,在画圈圈中心的地方,画出一个标识就完事了,但是发现这样写代码时简单了,但是每画一个节点,你就需要同时操作两个操作,很烦,很恶心。不过没关系,我会稍加思考,无所谓,我会出手。那我们就把画标识的东西写入画圈圈的内部吧,让他们一块操作(本来也是一个整体)。那怎么办呢,我们需要在画圈圈的同时把标识也画出来,那么api固有的画的方法就不是我们需要的啦,那我们就需要重写这个方法,也就需要我们继承这个类,派生出一个子类实现重新这个方法。
其实我们只要重新一个他的画方法就行了,设置坐标的其实不用重写(而且设置坐标的还不是虚函数),但是我没有重新他,导致不能正常工作,不起作用,所以我把这个坐标设置的也覆盖了。
来看看我们继承的子类,灰常简单。
class MyPoint:public QGraphicsEllipseItem
{
private:
QString ID;
int x,y,w,h;
public:
void setID(const QString &id)
{
ID = id;
}
void setRect(int x_,int y_,int w_,int h_)
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr)
};
看看画出来的圈圈,看着还行是吧,花了我好几个小时才画出来(我是真小白,半吊子qt,半吊子c++,佬勿喷);
![](https://img-blog.csdnimg.cn/img_convert/25358d0db04fed4218c5ebfb04718666.png)
画一个会画了,那画多个就一样的道理,不过我们需要重新一下这个画布的鼠标事件,让他根据鼠标的点击生成这个圈圈
看看这个结果展示
![](https://img-blog.csdnimg.cn/img_convert/3c04bcf74f4d65a451eedc7fda649405.gif)