咸鱼DoYoung  
做一条有理想的咸鱼

Qt 设置Qt::FramelessWindowHint后界面无法移动问题的一种解决方案

从别人代码中摘出来的

效果

思路

1. 写一个单例
2. 重写事件过滤器
1. 判断鼠标按下事件、鼠标释放事件、鼠标移动事件
2. 移动相应界面
3. qApp 注册过滤器

代码

.h

#ifndef APPINIT_H
#define APPINIT_H

#include <QObject>
#include <QMutex>

class AppInit : public QObject
{
    Q_OBJECT
public:
    explicit AppInit(QObject *parent = 0);
    static AppInit *Instance() {
        static QMutex mutex;
        if (!self) {
            QMutexLocker locker(&mutex);
            if (!self) {
                self = new AppInit;
            }
        }
        return self;
    }

    void start();

protected:
    bool eventFilter(QObject *obj, QEvent *evt);

private:
    static AppInit *self;

};

#endif // APPINIT_H

.cpp

#include "appinit.h"
#include "qapplication.h"
#include "qevent.h"
#include "qwidget.h"

AppInit *AppInit::self = 0;
AppInit::AppInit(QObject *parent) : QObject(parent)
{
	
}

// 主要代码
bool AppInit::eventFilter(QObject *obj, QEvent *evt)
{
    // 判断属性
    QWidget *w = (QWidget *)obj;
    if (!w->property("CanMove").toBool()) {
        return QObject::eventFilter(obj, evt);
    }
    // 保存鼠标位置
    static QPoint mousePoint;
    // 保存鼠标按下状态
    static bool mousePressed = false;

    QMouseEvent *event = static_cast<QMouseEvent *>(evt);
    // 鼠标按下
    if (event->type() == QEvent::MouseButtonPress) {
        // 鼠标左键
        if (event->button() == Qt::LeftButton) {
            mousePressed = true;
            mousePoint = event->globalPos() - w->pos();
            return true;
        }
    }
    // 鼠标释放 
    else if (event->type() == QEvent::MouseButtonRelease) {
        mousePressed = false;
        return true;
    }
    // 鼠标移动 
    else if (event->type() == QEvent::MouseMove) {
        // 同时满足鼠标为左键、鼠标为按下
        if (mousePressed && (event->buttons() && Qt::LeftButton)) {
            w->move(event->globalPos() - mousePoint);
            return true;
        }
    }

    return QObject::eventFilter(obj, evt);
}

void AppInit::start()
{
    // 让整个应用程序注册过滤器
    qApp->installEventFilter(this);
}

使用

main.cpp

#include <QtWidgets/QApplication>

#include "Client.h"
#include "appinit.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    AppInit::Instance()->start();

    Client w;
    // 设置"CanMove"属性
    w.setProperty("CanMove", true);
    w.showFullScreen();

    return a.exec();
}

由于在过滤器中是使用"CanMove"属性来判断的,

QWidget *w = (QWidget *)obj;
    if (!w->property("CanMove").toBool()) {
        return QObject::eventFilter(obj, evt);
    }

所以使用的时候只要设置"CanMove"属性为"ture"就可以了

    setProperty("CanMove", true);
posted on 2020-12-13 14:53  咸鱼Doyoung  阅读(936)  评论(0编辑  收藏  举报