QT实现拖动没有标题栏的窗口
void ShapedClock::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
dragPosition = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}
void ShapedClock::mouseMoveEvent(QMouseEvent *event) {
if (event->buttons() & Qt::LeftButton) {
move(event->globalPos() - dragPosition);
event->accept();
}
}
const QPoint & QMouseEvent::globalPos () const
Returns the global position of the mouse cursor at the time of the event. This is important on asynchronous window systems like X11. Whenever you move your widgets around in response to mouse events, globalPos() may differ a lot from the current pointer position QCursor::pos(), and from QWidget::mapToGlobal(pos()).
QPoint QWidget::mapToGlobal ( const QPoint & pos ) const
Translates the widget coordinate pos to global screen coordinates. For example, mapToGlobal(QPoint(0,0)) would give the global coordinates of the top-left pixel of the widget.
QPoint QWidget::mapFromGlobal ( const QPoint & pos ) const
Translates the global screen coordinate pos to widget coordinates.
===============================================华丽的分割线===============================================
当有子窗口时
以上只能用于没有子窗口的Widget,如果有父窗口就会发生父窗口不动,子窗口移动的尴尬情况。
以下代码用于让父窗口移动,FormMainCenter是子窗口,它的父窗口为MainForm:
头文件:
class FormMainCenter : public QWidget
{
Q_OBJECT
public:
explicit FormMainCenter(QWidget *parent = 0);
~FormMainCenter();
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
private:
Ui::FormMainCenter *ui;
//记录窗口拖动的位置
QPoint dragPosition;
QPoint orignalPositon;
};
CPP文件
void FormMainCenter::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
//计算点击的相对位置,确定鼠标是否点这个位置是否可以拖动(这里设定窗口上点击可拖动的范围为700*120)。
QPoint pt = mapFromGlobal(event->globalPos());
if(!(pt.x() < 700 && pt.y() < 120))
{
//qDebug() << tr("click ") << pt.x() << "," << pt.y();
orignalPositon.setX(-1);
orignalPositon.setY(-1);
event->accept();
return;
}
//使用dragPosition保存开始移动前鼠标点击的位置,用于计算拖动范围。
dragPosition = event->globalPos();
//使用orignalPositon保存开始移动前的主窗口位置
orignalPositon = parentWidget()->pos();
//qDebug() << tr("click ") << dragPosition.x() << "," << dragPosition.y();
//qDebug() << tr("parent pos") << parentWidget()->pos().x() << "," << parentWidget()->pos().y();
event->accept();
}
}
void FormMainCenter::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton)
{
//qDebug() << tr("mouse move pos:") << event->globalPos();
//qDebug() << tr("parent pos:") << parentWidget()->pos();
//qDebug() << tr("delta:") << (event->globalPos() - dragPosition);
// 当前鼠标的位置减去开始时保存的位置,就是拖动过程中的偏移量
// 将这个偏移量加上拖动前的父窗口位置,就是父窗口新的位置
if(!(orignalPositon.x() == -1 && orignalPositon.y() == -1))
parentWidget()->move(orignalPositon + (event->globalPos() - dragPosition));
event->accept();
}
}
移动一个窗口时同时移动另外一个窗口
//dragPosition 用于存放开始拖动时鼠标相对于本窗口的相对位置。
static QPoint dragPosition = {0,0};
void DlgAdvanceSetting::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
QPoint pt = mapFromGlobal(event->globalPos());
if(pt.y() < 50)
{
//qDebug() << "(mousePressEvent)Fram geometry topleft(" << frameGeometry().topLeft().x() << "," << frameGeometry().topLeft().y() << ")";
dragPosition = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}
}
void DlgAdvanceSetting::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton)
{
QPoint pt = mapFromGlobal(event->globalPos());
if(pt.y() < 50)
{
QPoint RelativePos = {165,0};
if(dlgMenuSetting)
{
//获取菜单设置窗口相对于本窗口的偏移,移动前后需要保证不变。
RelativePos = dlgMenuSetting->frameGeometry().topLeft() - frameGeometry().topLeft();
//qDebug() << "calc r = (" << RelativePos.x() << "," << RelativePos.y() << ");";
}
//移动自己
//qDebug() << "(mouseMoveEvent)Fram geometry topleft(" << frameGeometry().topLeft().x() << "," << frameGeometry().topLeft().y() << ")";
move(event->globalPos() - dragPosition);
if(dlgMenuSetting)
{
//移动菜单设置对话框,由于它逻辑上是高级设置的子窗口。
//由于事实上不是,那么在算出相对位置后,需要使用此窗口对应系统桌面的坐标调用它的move成员。
//qDebug() << "move r = (" << RelativePos.x() << "," << RelativePos.y() << ");";
QPoint globalPos = this->pos();
globalPos.setX(globalPos.x() + RelativePos.x());
globalPos.setY(globalPos.y() + RelativePos.y());
dlgMenuSetting->move(globalPos);
}
event->accept();
}
}
}
上一篇: 页面订单多选框批量操作
下一篇: 多选框组件
推荐阅读
-
WindowsForm移动一个没有标题栏的窗口的方法
-
QtQuick实现无边框窗口的拉伸,拖拽和自定义标题栏
-
QT实现拖动没有标题栏的窗口
-
C#实现Winform鼠标拖动窗口大小时设定窗口最小尺寸的方法
-
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例_javascript技巧
-
JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例_javascript技巧
-
Qt5开发学习总结(四)——资源文件的使用与主窗口QMainWindow实现登录框
-
QT布局管理(1)-分割窗口类QSplitter,可用鼠标任意拖动控件的大小
-
PyQt5实现无边框窗口的标题拖动和窗口缩放
-
WindowsForm移动一个没有标题栏的窗口的方法