概要
最近做控件随鼠标移动时,发现自己写的代码其实包含两种设置方式,在这里总结以下
1.记录控件的初始坐标,使用非控件坐标系
void XXX::mousePressEvent(QMouseEvent* event)
{
//在按下时,记录鼠标的初始坐标
mouse_pressed_point = event->globalPos(); //这里使用的是全局坐标
mouse_pressed_point = mapToParent(event->pos()); //这里使用的是父控件坐标系
widget_pos = this->pos();
}
void XXX::mouseMoveEvent(QMouseEvent* e)
{
//这里使用控件初始坐标+鼠标相对初始时的移动量, 在全局坐标系下
this->move(widget_pos + e->globalPos() - mouse_pressed_point);
//父控件坐标系就把 e->globalPos() 替换为 mapToParent(e->pos())
this->move(widget_pos + mapToParent(e->pos()) - mouse_pressed_point);
}
上述方式需要声明两个成员变量
1.mouse_pressed_point //鼠标按下时的鼠标位置
2.widget_pos //鼠标按下时的控件坐标
还可以优化一下,仅声明一个:
// in mouse press:
mouse_pressed_point = event->globalPos() - this->pos();
// in mouse move:
this->move(e->globalPos() - mouse_pressed_point);
如上述写法可以省略声明widget_pos的成员变量,
2.使用控件自身的坐标系(local坐标)
// in mouse press:
mouse_pressed_point = e->pos(); //鼠标在控件坐标系下的位置
// in mouse move:
this->move(this->pos() + e->pos() - mouse_pressed_point); //相对移动
此处同样可以做上面的优化操作(仅加减法的变化)
3.比较
第一种方式更容易理解
在批量设置控件移动时,第二种方式相比于第一种,无需记录所有控件初始的坐标,更优雅
更推荐第二种写法