既然父子窗体要同时移动,那么肯定和moveEvent(QMoveEvent*)这个事件有关了。同时移动子窗体的时候,也要把移动的信息告诉
父窗体,所以在子窗体中应该要持有父窗体的指针。
CCDialog::CCDialog(QWidget* parent)
:m_parent(parent)//在父窗体中实现这个子窗体的时候,将this指针传给子窗体的成员变量
void CCDialog::moveEvent(QMoveEvent *e)
{
QDialog::moveEvent(e);
m_point = this->pos();
(static_cast<CCWidget*>(m_parent))->onMove(m_point);
}
接着就是重载moveEvent事件了,先记录下子窗体的当前位置,然后告诉给父窗体。
void CCWidget::onMove(QPoint& childPoint)
{
if(m_nFlag < 3)
{
m_nFlag++;
m_diff = childPoint- m_parentPoint;
return ;
}
move(childPoint- m_diff);//父窗体移动到 子窗体 与 原先父子窗体差值 的差值处。
}
void CCWidget::moveEvent(QMoveEvent *e)
{
QWidget::moveEvent(e);
m_parentPoint= this->pos();//在程序初次启动的时候记录下父窗体的当前位置
}
void CCWidget::slotOpen()
{
m_dlg->exec();//槽,打开子窗体
}
这其中CCWidget::moveEvent代码最为复杂,因为我发现一个子窗体从头到尾显示出来,共经历了三次位置的变化:
(0,0)->(x1,y1)->(x2,y2) x1<x2,y1<y2
所以用了一个int类型的变量m_nFlag获得子窗体的最终位置,再把这个位置和父窗体位置做减法,得到最终的差值。
这样,子窗体不论移动到哪儿,把它的位置减去差值,父窗体移动到差值,就能实现同步移动了。
我用this->pos()求位置,是因为移动事件e->pos()的值是变化的。你不移动父窗体,但是当显示子窗体后,它的值是变化的。
在视觉上没有抖动变化,但如果你用它做变量,这个差值就会体现出来了,我的程序中它会使父窗体在子窗体出现的一瞬间的时候
抖动一下。而this->pos()无变化。
其实也有个好办法,让子窗体一出来就固定在某处,就不需要m_nFlag变量了,那就是在构造函数中使用setGeometry()函数。
最后的最后,在子窗体关闭之后,得更新m_diff,因为下次子窗体如果显示的话,会在原来的地方,但是,父窗体已经不再原来的地方了
,所以要在子窗体的关闭信号对应的槽中使m_nFlag=1,以便程序会更新m_diff的值。