功能实现:
窗口分为由操作系统管理的非用户区(Non-Client Area)和默认子窗口不能拖动的客户区(Client Area)。
通常情况只能通过点击标题栏即非用户区拖动窗口。此程序实现整个窗口任意位置的拖动。
代码实现:
1.声明成员变量:
bool m_dragging; //“是否拖动”状态变量
QPoint m_mousestart; // 鼠标自左键点击开始移动的初始位置
QPoint m_framestart; // 鼠标移动前的整个框架相对桌面位置
2.Mainwindow.cpp
#include "Mainwindow.h"
#include "ui_Mainwindow.h"
#include <QMouseEvent>
CMainWindow::CMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::CMainWindow)
{
ui->setupUi(this);
m_dragging=false; //“是否拖动”状态变量 初始值设为false
}
CMainWindow::~CMainWindow()
{
delete ui;
}
void CMainWindow::mousePressEvent(QMouseEvent*event) //重写虚函数
{
if(event->button()==Qt::LeftButton) //button判断鼠标产生的事件(按下)是否为左键
{
m_dragging=true; //“是否拖动”状态变量 被置为true
m_mousestart=event->globalPos(); //获取鼠标初始位置
m_framestart=frameGeometry().topLeft(); //获取整个框架初始位置
}
}
void CMainWindow::mouseMoveEvent(QMouseEvent*event) //重写虚函数
{
//buttons判断产生事件的鼠标状态仍然为左键 且“是否拖动”状态变量已被置为true
if(event->buttons()==Qt::LeftButton&&m_dragging)
{
QPoint m_mousenow=event->globalPos(); //获取鼠标当前位置
move(m_framestart+m_mousenow-m_mousestart); //获取整个框架移动到什么位置
}
}
void CMainWindow::mouseReleaseEvent(QMouseEvent*event) //重写虚函数
{
if(event->button()==Qt::LeftButton) //button判断鼠标产生的事件(松开)是否为左键
{
m_dragging=false; //“是否拖动”状态变量置为FALSE
}
}
问题总结:
1、button()和buttons()的区别:
在click事件中使用button(),在move事件中使用buttons()。
官方教程:
Qt::MouseButton QMouseEvent::button () const //返回产生事件的按钮;
Qt::MouseButtons QMouseEvent::buttons () const //返回产生事件的按钮状态;
前者是鼠标move事件总是返回 Qt::NoButton,后者函数返回当前按下的所有按钮。 假设你的鼠标左键已经按下。
如果移动鼠标,会发生的move事件,button返回Qt::NoButton,buttons返回LeftButton。 再按下了
右键,会发生press事件,button返回RightButton,buttons返回LeftButton|RightButton
再移动鼠标,会发生move事件,button返回Qt::NoButton,buttons返回LeftButton|RightButton
再松开左键,会发生Release事件,button返回LeftButton,buttons返回RightButton。
也就是说,button返回“那个按钮发生了此事件”,buttons返回”发生事件时哪些按钮还处于按下状态”
2、获取窗口当前位置:
QRect QWidget::frameGeometry();
//函数返回QRect类型的矩阵,表示整体框架相对桌面的位置; 如果使用rect()函数,只能得到客户区相对位置。
QPoint QRect::topLeft();
//函数返回QPoint类型的点坐标,表示矩阵rect左上角点的全局坐标。