直接重写mouse的事件
代码实现:button
返回 哪个按钮造成了此事件,buttons
返回 发生此事件时哪些按钮还处于按下状态
#include <QMouseEvent>
private:
// 记录坐标差值
QPoint diff;
QPoint now_pos;
bool m_MouseDrag = false; // 一定要记得初始化为false
void Dialog::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton) {
m_MouseDrag = true;
// 鼠标在全局的位置 // 界面左上角在全局的位置
this->diff = event->globalPos() - this->frameGeometry().topLeft();
// 如果是通过界面里的某个部件,进行拖拽移动,获取界面左上角在全局的位置是比较麻烦的
// 需要用其父类来获取,直接调用parent()函数得到是Object类型,没有frameGeometry成员函数
// 需要强转为父类 ((QWidget *)this->parent())->frameGeometry.topLeft()
// 这里只是以父类为 QWidget 为例
return;
}
QDialog::mousePressEvent(event);
}
void Dialog::mouseMoveEvent(QMouseEvent *event)
{
if(m_MouseDrag && event->buttons() == Qt::LeftButton) {
QPoint now_pos = event->globalPos() - this->diff;
this->move(now_pos);
return;
}
QDialog::mouseMoveEvent(event);
}
void Dialog::mouseReleaseEvent(QMouseEvent *event)
{
// 释放鼠标事件(左键)
if(event->button() == Qt::LeftButton){
m_MouseDrag = false;
return;
}
QDialog::mouseReleaseEvent(event);
}
实现一个类
appinitdrag.h
#include <QObject>
#include <QMutex>
#include <QApplication>
#include <QWidget>
#include <QMouseEvent>
class AppInitDrag : public QObject
{
Q_OBJECT
public:
AppInitDrag();
static AppInitDrag* GetInstance();
void start();
protected:
bool eventFilter(QObject *obj, QEvent *event);
private:
static AppInitDrag *self;
};
appinitdrag.cpp
文章来源:https://www.toymoban.com/news/detail-765959.html
#include "appinitdrag.h"
AppInitDrag::AppInitDrag()
{
}
AppInitDrag *AppInitDrag::self = 0;
AppInitDrag *AppInitDrag::GetInstance()
{// 双重检查锁定机制(Double-Checked Locking)的单例模式
if(self == nullptr) {
// 避免多个线程同时通过锁定和创建实例
QMutex mutex; // 用于实现互斥锁, 确保多线程环境下对 self 的访问是安全的
// QMutexLocker 是Qt提供的辅助类,它简化了对QMutex的使用,通过在其初始化时自动锁定和解锁互斥锁
QMutexLocker locker(&mutex); // RAII 风格的锁定对象,能确保只有一个线程能够持有 mutex
if(self == nullptr) {
// 在锁定的情况下再次检查 self 是否为 nullptr,以防止多个线程同时通过第一次检查
self = new AppInitDrag;
}
}
return self;
}
void AppInitDrag::start()
{
/*
QApplication(通常简写为qApp)是Qt框架中的一个核心类,用于管理应用程序的控制流和全局设置。
它是Qt应用程序的主要入口点,并提供了一些基本的应用程序功能,包括事件处理、国际化支持、应用程序广播以及整个应用程序的全局设置
*/
//将 this 注册为事件过滤器,从而捕捉特定的鼠标事件
qApp->installEventFilter(this); // 安装事件过滤器
}
// 使得具有 canMove 属性的 QWidget 窗口能够通过鼠标左键拖动来移动的功能
bool AppInitDrag::eventFilter(QObject *obj, QEvent *event)
{
QWidget *w = (QWidget *)obj;
if (!w->property("canMove").toBool()) {
return QObject::eventFilter(obj, event);
}
static QPoint mousePoint;
static bool mousePressed = false;
QMouseEvent *mevent = static_cast<QMouseEvent *>(event);
if (mevent->type() == QEvent::MouseButtonPress) {
if (mevent->button() == Qt::LeftButton) {
mousePressed = true;
mousePoint = mevent->globalPos() - w->pos();
return true;
}
} else if (mevent->type() == QEvent::MouseButtonRelease) {
mousePressed = false;
return true;
} else if (mevent->type() == QEvent::MouseMove) {
if (mousePressed && mevent->buttons() == Qt::LeftButton) {
w->move(mevent->globalPos() - mousePoint);
return true;
}
}
return QObject::eventFilter(obj, event);
}
在 main.cpp
里添加 appinitdrag.h
,然后在要设定拖拽的 widget
窗口的构造函数里添加代码文章来源地址https://www.toymoban.com/news/detail-765959.html
this->setProperty("canMove", true); // 设置可以拖拽的属性
this->setWindowFlags(Qt::FramelessWindowHint); // 设置无边窗
到了这里,关于Qt 鼠标左键推拽界面的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!