继续第四天的demo
总结了之前的经验教训,我重新开一个项目项目,先给出demo的结果吧,第一张是第一次写的demo,第二张图是成品的demo
结果还是比较满意的,虽然过程中有遇到的问题不是我自己独立解决的。。。相比于第一个demo,提升了鼠标和子控件的配合的灵敏度,同时保证了在鼠标出界的时候,子控件是保持在父窗口中的,同时依然在qt的应用程序输出窗口输出手柄的坐标
说一下中间遇到的坎坷吧:
- 一开始我是重新定义了一个继承于QLabel的类,在这个类中重写mouseEvent的三个函数,但是结果并不如人意,因为要控制鼠标和这个handle同时移动,同时保持handle保持在主窗口中不能出界,如果在这个继承于QLabel的类中重写鼠标事件,即使是在父窗口中再次重写鼠标事件也无济于事,因为根据QT的机制/规则,如果父窗口和子窗口重写了同一个函数,那么编译器会首先执行子窗口重写的函数,如果子窗口没有重写这个函数,那么就会向上寻找,也就是向这个子控件的父控件寻找,父控件可能不执行也可能覆盖子控件执行的操作,这是非常不规范的。
所以在这一次的demo中只有一个mainwindow类继承QMainWindow类,在这个类中重写鼠标事件的三个函数,使用isin函数确定鼠标是否在子控件handle中。 - 在这个demo中,首次尝试使用Pixmap添加背景图片(之前用的是setstylesheet)和使用QRect来寻找控件的中心坐标和左上角的坐标
- 在使用Pixmap添加背景图片的时候,为了让背景图片填充到控件中,需要使用setScaledContents(1)
- 还有就是使用信号的问题,我一开始是直接把定时器放到事件中的,但是后来发现不可行。因为如果在事件中执行定时器,那么在这个不断(随时有可能)被调用的事件中定时器就会不断的执行,在定时器中我放的是保证handle和鼠标一起移动的槽函数,所以含义是,鼠标移动一次,handle也跟着移动到相应的位置就可以了(是一对一的),而如果把定时器放到鼠标事件中,显然鼠标移动一次,定时器中的handle移动就会跟着执行多次(就变成一对多了)。那么在这种情况下,定时器就不适用了,我是直接将槽函数放到事件中了(槽函数也是成员函数,可以当成普通的成员函数使用)
- 另外还需要保证handle不越界,所以在mouseMoveEvent中检测鼠标指向的handle是否越界,第一使用移动函数(槽函数)将鼠标和手柄绑定起来,让手柄跟随鼠标移动(这一步一定是第一步,要不然放到后面的话,检测越界的操作会被覆盖,都是泪),再使用handle的geometry获取手柄的左上角的x,y坐标,判断x,y坐标加上手柄的尺寸是否大于主窗口的尺寸
还有一些话
实际上还有很多问题,时间太长没办法全部记起来,但是重要的地方都记下来了,本来打算明天做一个圆形的手柄,但是今天又发了新任务,感觉难度比较大,可能没时间写了,如果想查看源码练手欢迎访问我的github主页,这是我练习qt的仓库,欢迎大家star