范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

高仿富途牛牛如何去管理超级多的小窗口

  一、概述
  代码写的久了,什么功能都想搞点儿模式。不知道是不是只有我一个人这么想的,做功能时不在是只为了完成功能,而是在完成功能的同时会去考虑可扩展性怎么样?哪块儿的代码可以复用?又或者哪里需要留更多的接口?这两个类之间是不是可以加一个协作类?总之各种想法都出来了。
  假设说有这样一种场景,我们通过一个入口界面,上边有很多种按钮,当我们点击上边的按钮时,程序就会生成一个小窗口。这些小窗口他们的外在行为基本一致,只是窗口里边展示的内容各不一样。
  总结一下应该是这样的 窗体可以通过标题栏进行拖拽 鼠标移动到边界可以进行放大缩小 鼠标选中时边框高量显示 标题栏具有名称、关闭和各种各样的菜单 不同功能窗体的菜单内容不一样,展示风格也可能完全不同 标题栏和中心窗体也有交互 连续点击一个按钮时,生成同类型的窗体不能完全覆盖
  用过富途牛牛的同学应该对这个功能比较清楚一点,富途中的交易模块也是如此,工具箱里支持各种小窗体生成,并且都有各自丰富的内容。
  这么多繁杂的窗体,富途是怎么管理的呢?
  本篇文章就来仔细挖掘下这个功能,我们也来实现一个小窗口管理功能。 二、效果展示
  如效果图所示,我们之前所说的几个功能点都已经有了,并且在配色上比之前的demo程序也有改善,当然要投入使用还是需要设计师同学经过专业的指点。
  三、功能类
  为了实现这个窗口管理功能,思考的头都快要炸掉了,不是因为功能有多复杂,而是作为一个开发人员,我想的太多了,总是会出现一种幻觉,产品经理可能会提出这样那样的新需求,测试也可能会给你报一个莫名其妙的问题。
  最最关键的还是我们要对自己写的代码有一个基本要求。结构必须合理、减少冗余和耦合,让其他人阅读代码时使用最小的成本,
  为了做这个窗口管理功能,我也是想了好久,总是想着设计的更合理一些,别人在使用时就会更简单一些,使用成本也会更小。
  为此,我引入了好几个关键类,都是辅助管理窗口的,下面先来一张类图,这是我使用starUML画的,不是特别规范,主要是为了说明这些类的功能,以及他们之间的一个关系,图上都用注释写出了每个类的大概作用。
  从图上也可以看出来,类中就是一个简单的名字,我没有把类的接口都贴上去,一个是时间问题,另一个我也觉着不是特别有必要,因为我本身对这个画图工具使用就不是特别深入,所以这里就只提供了简单的版本。大家凑合看吧,对理解设计思路还是有很大的帮助。
  本篇文章主要讲的是小窗口管理,但是这里主要是通过讲述 迷你报价  小窗口来说明怎么去管理炒鸡多的小窗口
  从上边图中可知,关键类有以下这些 ISmall:业务窗口接口类,负责和SmallWidget进行通信 MiniPriceSmall:迷你报价小窗口的中心窗口 SmallWidget:小窗口模板类,这是所有小窗口的外壳类,包含了标题栏。迷你报价窗口就是构造了这么一个类,然后设置了一个中心窗口MiniPriceSmall。其他的业务窗口都是使用同样的模式 ViewModePanel: 迷你报价  工具菜单按下时,弹出的视图列表,主要是为了修改显示模式。仔细观察效果展示中的gif图,菜单"M"被点击时,弹出了显示模式  窗口,随后在显示模式窗口任意选项上单击后,迷你报价  窗口上都出现了一行欢迎文本--感谢您的使用,您选择了模式:XSmallContext: 小窗口  管理上下文类,主要负责处理我们定制好的外壳类SmallWidget和业务窗口MiniPriceSmall(其他更多业务窗口)之间的消息通信SmallGroup:小窗口组管理者,主要负责磁力吸附这个功能,详情参看高仿富途牛牛-组件化(二)-磁力吸附这篇文章 SmallFactory: 小窗口  工厂,负责构造各式各样的小窗口ToolBoxDialog:工具箱的实现没有专门去写文章讲解,需要了解的可以参看高仿富途牛牛-组件化(三)-界面美化这篇文章,第三小节对工具箱做了简单的讲解 四、设计上的考虑
  首先,我自己做的是一个组件化的功能,我需要考虑的东西也是更多的,不仅仅要把功能完成,更多的是要去考虑,别人用的时候代价怎么可以更小?可以复用的代码,我尽量都提取出来,写成共性的东西,其他开发在做相应业务模块时,只需要考虑真的和他们有直接关系的地方。
  这里我们就拿 迷你报价  这个功能来说事,看看怎么去设计是合理的,或者说目前看起来是合理的,可能后期根据需求,我们的结构或许会进行一定的调整。1、功能拆分
  单独拿出一个 迷你报价  功能来说,可能100%的人都会说很简单,这有什么难的,我刚参加工作那会儿百度百度也都能做出来。可是往往把一些简单的东西,抽象抽来,让程序变得更简单这件事情本身就是一件比较难的事情。
  迷你报价  这个窗口总的来说可以分为上下两部分:上边标题栏和下面内容展示区域
  标题栏
  标题栏是每一个小窗口都有的,因此这里我们肯定是要单独提出来作为一个公有的东西,当其他开发做自选股、小时钟、短线精灵这些小窗口时,标题栏的移动事件他们就根本不需要考虑了。
  细心的同学可能会发现了,标题栏上还有一些不认识的按钮,这些按钮时干什么的呢?
  虽然标题栏已经被公有化,但是标题栏上的按钮可不是这么想的,他们的行为要根据底部内容窗口的类型决定,因此这里就有了一定的变化。
  为了适应这个变化,我自己定义了一个接口类ISmall,主要是让内容窗口进行继承的,也就是说内容窗口需要重写这个接口类的一些接口,来完成运行时的一些设定。
  比如说, 迷你报价  标题栏按钮显示有哪些?按钮显示时都有哪些功能?按钮点击时该有什么样的相应?按钮点击后弹出的面板点击被点击了,内容窗口做何处理等等。
  内容展示
  内容展示窗口就比较简单了,这里有2个选择,继承ISmall接口类或者不继承 继承-意味着内容窗口需要和外壳窗口进行消息通信 不继承-我们就只是展示数据的,不需要进行消息通信
  事实上大多数的内容窗口都是需要继承ISmall这个接口类的,纯展示而没有交互的功能几乎没有。 2、关键类
  ISmall
  ISmall接口类是毫无疑问的关键类,它是一个纯虚类,继承它的类都必须实现它的所有接口,如下代码所示 /** * 简介: 小窗口上的回调事件,需要通知中心窗体 */ struct ISmallCall { 	virtual ViewMode ViewType(SmallToolType) = 0; 	virtual void GetItems(QVector &) = 0; 	virtual QSize GetSize() const = 0; 	virtual void Notify(const QString &) = 0; };
  GetSize()、GetItems()这些接口都是获取数据接口,外壳类SmallWidget,会根据当前中心窗口返回的定制数据去初始化自己。
  比如说效果图中展示的 显示模式  面板,这个面板中的数据内容,就是迷你报价类MiniPriceSmall重写了getItems接口之后,给外壳类提供的数据,并且制定了事件触发时使用的显示模式为视图。
  迷你报价  类重写的数据准备接口如下void MiniPriceSmall::GetItems(QVector & items) { 	for (int i = 0; i < 9; ++i) 	{ 		DataItem item; 		item.name = "A" + i; 		item.type = item.name; 		item.img = "./image/mainWindow/tquant-btn_normal.png"; 		items.append(item); 	} }
  目前接口类中的接口还不是特别完善,根据后续业务功能的变化,接口肯定还会继续增多。
  MiniPriceSmall
  这个类是迷你报价的数据展示类,他继承自QWidget窗口类和ISmall接口类,界面搭建这里我就不说了,两个原因:其一是这里的界面本身就是空的,其二也是比较关键的,中心窗口的内容是根据业务类型决定的,后期根据不同开发负责的功能自己去搭建。通常情况下这里都是别人已经封装好了的控件,有必要的时候在使用一个简单外壳类包一层即可。
  除过界面之外,就是ISmall的接口实现类了,一部分接口是给外部SmallWidget提供数据的,而另一部分接口就是响应外部事件。
  目前来说,响应外部接口事件就只有一个接口Notify,比较重要,消息响应时根据参数来区分消息类型
  SmallWidget
  小窗口类,为所有小窗口的外壳类,提供了定制化的标题栏和边界缩放。功能实现不难,需要的可自行百度。
  ViewModePanel
  显示模式  面板,主要是一些小窗口可以根据该面板的选项可以进行显示模式的重组,并且可以切换窗体的大小等等。效果展示中我们只是修改了显示的问题,不过实现起来思路是一样的,最主要的是内容窗体已经接收到我们传递的消息。
  SmallContext
  这是一个比较关键的类,当时想了很久,到底要不要加。
  这个类主要负责的功能就是同步小窗体外壳类SmallWidget和内容窗体类之间的消息传递。 当SmallWidget想要给内容窗体传递消息时,会通过ISmall接口类进行发送指令,因为内容窗体是继承了这个ISmall接口类的 当内容窗体想给外壳发送消息时,是通过ISmall的接口调用来到达目的的,严格来说其实是外壳窗体主动跟内容窗体要的消息内容。
  当SunPanel面板通过工厂类SmallFactory进行构造小窗口时,会把SmallWidget和构造好的内容窗体进行注册,并开始接收SmallWidget发送过来的事件请求。 void SmallContext::RegisterSmallWidget(SmallWidget * widget, ISmallCall * call) { 	m_itemMap[widget] = call;  	connect(widget, &SmallWidget::ClickedButton, this, &SmallContext::HandleEvent); }
  当工具栏点击了"M"按钮时,SMallWidget就会给SmallContext发送事件请求,并附带相关参数,这里SmallWidget发送了 显示模式  选择事件,下面是SmallContext的处理方式void SmallContext::HandleEvent(int type, const QPoint & globalPos) { 	if (SmallWidget * widget = dynamic_cast(sender())) 	{ 		if (m_itemMap.contains(widget)) 		{ 			if (ISmallCall * call = m_itemMap[widget]) 			{ 				ViewMode view = call->ViewType(SmallToolType(type));  				if (view == VM_VIEW) 				{ 					ShowView(widget, call, globalPos); 				} 			} 		} 	} }
  SmallFactory
  最后就是工厂类了,一看名字就知道,他是一个工厂,专门负责生产小窗口的,对工具箱来说,他只知道给SubPanel发送显示一个小窗口这个指令,但是SubPanel自己其实也不会去真正的构造一个小窗口,原因其实很简单,单个的构造一个小窗体其实没问题,但是当小窗体种类多起来时,需要维护的消息就随之增多。
  重构之后的代码看起来像这样,当SubPanel类需要一个小窗口时,他只需要这么干就行 SmallWidget * smallWidget = m_pSmallFactory->CreateWidget(type, subContent); subContent->AddSmallWidget(smallWidget);  smallWidget->move(m_pSmallFactory->GetPos(type, subContent)); smallWidget->show();
  调用工程的CreateWidget方法,构造一个小窗口,然后加入到自己的布局中
  这里还有一个比较关键的问题,就是窗口初始位置管理,我们在工厂里维护了一个位置偏移量,当连续请求同一类型的小窗口时,我们会给这个偏移量增加一个固定值,使得连续请求时,同一类型的小窗口获取到的位置是有规律的变化 void SmallFactory::UpdateOffset(bool change, QWidget * parent) { 	if (change) 	{ 		m_offset += QPoint(13, 13); 	} 	else 	{ 		m_offset = QPoint(0, 0); 	}  	QRect r = parent->rect(); 	if ( m_offset.y() > r.height() / 4  		|| m_offset.x() > r.width() / 4) 	{ 		m_offset *= -1; 		m_offset.setX(m_offset.x() - 15); 	} }

探场成都SKP争论漩涡里的高奢样本2月中旬,三火姐姐在四天里密集走访了成都近20个项目,希望通过时空的近距离,感受成都这座城市如火如荼的商业氛围,以及消费者的偏好与变化。去年12月20日开业的成都SKP,曾经在社交成都蓉城教练谈木塔力甫在U20的表现潜力大,还有进步空间封面新闻记者陈羽啸林珏瑶北京时间3月6日晚,男足亚洲杯小组赛D组第二轮比赛中,中国队以2比0战胜卫冕冠军沙特队。来自成都蓉城足球俱乐部的小将木塔力甫成为本场比赛获胜的功臣。在比赛下四川成都杜甫草堂兰花展吸引民众观展来源中新社2023年3月5日,四川成都,由杜甫草堂博物馆成都市兰花协会共同主办的盛世花开迎大运,雅兰幽香满蓉城杜甫草堂兰花展吸引民众前来观展。中新社记者安源摄2023年3月5日,四全面停用国产芯片!PC厂商戴尔官方声明,外媒赢家或是联想大家都知道,去年对我们中的大多数人是很不友善的。特别是在高强度的风险控制政策下,这场瘟疫对我们造成了无数的负面影响。同时,也对我国的电子零售业产生了巨大的影响。到了2023年,大部杭州亚运会官方特许商品在天猫独家新品首发3月7日,亚组委在天猫独家首发首批杭州亚运会电竞特许商品,以迎接亚运会倒计时200天。此外,亚组委还带来了一款神器售价为398万的宝器合尊至尊永恒纪念版。宝器合尊通体为名贵玉石打造历史上三个假太监谋杀皇帝,欺辱皇后,让太后生孩子太监又称宦官,大多家境贫寒,受宫刑入宫为奴,在古代地位极低。但有些太监作恶多端,以一己之力,搅得朝堂腥风血雨,危害皇权,遗臭万年也有些太监身残志坚,忠心为主,为国家的发展做出贡献,1948年老蒋败逃时,因飞机超重抛下的十块石头,如今已成镇国之宝1948年,国民党在大陆接连战败让蒋介石开启了他前往台湾的计划。在他本人到达台湾之前蒋介石就命人将许多珍贵的文物以及黄金外汇都运往台湾,来为以后反攻大陆做准备。在当年的十二月二日,中国大运河的先声中国大运河的先声浙东运河又名杭甬运河,位于中国大运河最南端,是中国出现形成最早和连线运用时间最长的运河之一。中国大运河的先声,吴越争霸的生命线是对它最生动的概括。浙东运河全长239古希腊神话阿喀琉斯之踵是啥梗?第一猛将脚踝中箭就挂了?古希腊神话博大精深意味深长,对后世文学绘画戏剧建筑雕塑等各方面都有深远的影响。各种宏大的场面光怪陆离的故事情节充满人性色彩的各路神祇英勇又悲壮的英雄人物,几千年后仍然让人神往。选材商鞅重刑治国是手段,而不是目的!株连在古代一般不被严格执行在我们中国的历史上,株连是一种几乎与历史同样古老的酷刑。相传我国公认的第一个世袭制君主夏启,为了巩固自己的权威,就灭了支持伯益的有扈氏的族。虽然不知道夏启灭了有扈氏几族,但足却可确嘉庆帝问和珅贪那么多钱,花得完吗?和珅的回答让嘉庆沉默良久在铁齿铜牙纪晓岚这部电视剧之中,王刚所饰演的贪官和珅似乎早已深入人心。在真实的历史之中,和珅也没有落得一个好下场。据悉,嘉庆帝曾问狱中的和珅贪污那么多的钱,你究竟能不能花完?没想到
存款300万提前退休,有网友不淡定了澎湃特约评论员马青上海一对夫妻决定提前退休了,妻子33岁,丈夫43岁。两个人失业后没有找到合适工作,后来一盘算,银行里有300万存款,有房有车无娃无贷,双方老人各有退休金,为什么还58岁时尚博主爆红!大胆辣妹风引网友围观这身材比我还好开篇先来个无奖竞猜你觉得下图中的辣妹今年几岁?说出来你可能不信这位身材看起来20岁的辣妹,其实今年58岁。她是来自加拿大的银发时尚博主,GreceGhanem。和大家印象中的中老年都是骁龙8,哪款性价比更高?网友投票选一加Ace2最多如果问现在哪个价位段的手机最值得购买?那么我会推荐你去看看2500元到3500元档的产品。在这个价位区间,很多手机厂商都会选择在手机上搭载骁龙8处理器,这颗处理器不但拥有非常好的性永定区西溪坪中心完小开展诺如病毒预防宣传教育活动红网时刻张家界2月27日讯(通讯员高自安田学成)为了防止校园传染病的流行,维护在校师生的身体健康,2月27日上午,永定区西溪坪中心完小开展了预防诺如病毒及春季传染病知识宣传教育活动加强非遗保护传承和合理利用文化和旅游部扎实推动落实代表委员建议提案2023年2月,文化和旅游部人力资源社会保障部国家乡村振兴局公布了66个非遗工坊典型案例,山东省高密市昌盛泥塑农民专业合作社联合社非遗工坊名列其中。依托国家级非遗项目聂家庄泥塑,非封门葬不可取,死者为大,还是让女子早日入土为安吧封门葬,这是民间最毒的葬法。是把棺材直接放在客厅大门口,再封住大门,让房子成为墓地,采取这种安葬方法,据说后代子孙好几代人都翻不了身。安阳24岁女子在被枕边人连砍8刀毙命,惨烈程度朔尔茨押注印度,德国商界却这么说参考消息网2月27日报道(文舒梦王自强)在刚刚过去的周末,德国总理奥拉夫朔尔茨结束了对印度的闪电访问。朔尔茨此时为何访问印度?成效几何?这些问题成为国际社会关注的焦点。德国之声电台小米首款汽车明年量产,申请摩德纳商标银河之光原型车涉嫌抄袭?马斯克计划开发对标ChatGPT的产品比亚迪日本法人回应使用六价铬问题蔚来或计划在合肥建设其首家电池工厂成都街头一越野车多次追撞轿车福特电池供应商称F150Lighting电动皮卡文化周刊火塘烟影李纪镜儿时的冬夜,和父亲一起到伯父家去向火(烤火),好像是每天的必修课。出堂屋门向右循檐阶走到尽头,右拐,傍房屋山墙走几十步就到了伯父家。即使下雨下雪也不碍事。下雨下雪就在布鞋棉鞋制止食品浪费天地粮心珍食莫蚀一粥一饭,当思来处不易半丝半缕,恒念物力维艰。为制止食品浪费,各地各级市场监管部门发布消费提示,助力全社会树立文明节俭消费理念,推进反餐饮浪费工作。本报综合如下消费者按量买勿铺张合中信证券预计到2025年4680动力电池需求超过100GWhe公司讯,中信证券研报认为,4680电池具备高能量密度高充放电功率低成本的优点,是特斯拉引领的新一代圆柱电池,未来有望成为圆柱动力电池标准型号。预计到2025年,4680动力电池需