关于自定义的Qt无边框窗体

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39568531/article/details/84643112

       现在桌面软件的设计风格已经偏向于扁平化了。那么基于Qt开发的桌面应用也会常常被提出扁平化无边框的需求。怎么去掉应用程序旁边土到渣的边框呢?本文应该可以帮到你。

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QBaseFramelessWidget
TEMPLATE = app


SOURCES += main.cpp\
        qbaseframelesswidget.cpp \
    settingframelesswidget.cpp

HEADERS  += qbaseframelesswidget.h \
    settingframelesswidget.h
 /// qbaseframelesswidget.h
#ifndef QBASEFRAMELESSWIDGET_H
#define QBASEFRAMELESSWIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QMouseEvent>
#include <QStyle>
#include <QIcon>
#include <QString>
#include <QDebug>

class QBaseFramelessWidget : public QWidget
{
    Q_OBJECT

public:
    QBaseFramelessWidget(QWidget *parent = 0);
    ~QBaseFramelessWidget();

    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
public:
    /// 窗体移动事件的点
    QPoint windowPos;
    QPoint mousePos;
    QPoint dPos;
private slots:
    /// 最小化窗体
    void onMin( bool );
    /// 关闭窗体
    void onClose( bool );
private:
    /// true表示当前窗口状态为normal,图标应显示为max
    bool minOrNormal;
public:
    /// 显示最大或者normal的图标按钮
    QPushButton* m_minOrNormalPushBtn; 
    /// 关闭按钮
    QPushButton* m_closePushBtn;
};

#endif // QBASEFRAMELESSWIDGET_H
/// qbaseframelesswidget.cpp
#include "qbaseframelesswidget.h"

QBaseFramelessWidget::QBaseFramelessWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowFlags(Qt::FramelessWindowHint |
                         Qt::WindowSystemMenuHint |
                         Qt::WindowMinMaxButtonsHint);


    minOrNormal = true; /// 初始化默认为normal状态
    m_minOrNormalPushBtn = new QPushButton(this);
    m_closePushBtn = new QPushButton(this);
    m_minOrNormalPushBtn->raise();
    m_closePushBtn->raise();

# if 0    ///  这里只是做显示,具体大位置可以自定义设置
    m_closePushBtn->setGeometry(QRect(300,8,25,25));
    m_minOrNormalPushBtn->setGeometry(QRect(330,8,25,25));

    m_closePushBtn->setFlat(true);
    m_minOrNormalPushBtn->setFlat(true);
#endif

    QIcon icon;
    if( minOrNormal ){/// true means normal
        /// normal时显示最小化图标
        icon = style()->standardIcon( QStyle::SP_TitleBarMinButton );
        m_minOrNormalPushBtn->setIcon( icon );
        m_minOrNormalPushBtn->setToolTip(QObject::tr("Min"));
    }

    icon = style()->standardIcon( QStyle::SP_TitleBarCloseButton );
    m_closePushBtn->setIcon( icon );
    m_closePushBtn->setToolTip(QObject::tr("Quit"));

    connect( m_minOrNormalPushBtn, SIGNAL(clicked(bool)), this, SLOT( onMin(bool)) );
    connect( m_closePushBtn, SIGNAL(clicked(bool)), this, SLOT( onClose(bool)) );

}

QBaseFramelessWidget::~QBaseFramelessWidget()
{

}
void QBaseFramelessWidget::onMin(bool)
{
    if( windowState() != Qt::WindowMinimized ){
        setWindowState( Qt::WindowMinimized );
    }
    m_minOrNormalPushBtn->setToolTip(QObject::tr("Min"));
}

void QBaseFramelessWidget::onClose(bool)
{
    emit close();
}


void QBaseFramelessWidget::mousePressEvent(QMouseEvent *event)
{

    this->windowPos = this->pos();           // 获得部件当前位置
    this->mousePos = event->globalPos();     // 获得鼠标位置
    this->dPos = mousePos - windowPos;       // 移动后部件所在的位置

}

void QBaseFramelessWidget::mouseMoveEvent(QMouseEvent *event)
{
    this->move(event->globalPos() - this->dPos);
}

想要写出既要无窗体可移动,又要包含自己特性的窗体的话,只需要继承上面的类,写一个子类就可以了。

#ifndef SETTINGFRAMELESSWIDGET_H
#define SETTINGFRAMELESSWIDGET_H

#include <QObject>
#include <QWidget>
#include "qbaseframelesswidget.h"

class settingFramelessWidget : public QBaseFramelessWidget
{
public:
    settingFramelessWidget();
};

#endif // SETTINGFRAMELESSWIDGET_H
#include "settingframelesswidget.h"

settingFramelessWidget::settingFramelessWidget()
{

}

在main.cpp函数中执行,测试效果:

#include "qbaseframelesswidget.h"
#include <QApplication>
#include "settingframelesswidget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    QBaseFramelessWidget w;
//    w.show();

    settingFramelessWidget sfw;
    sfw.show();

    return a.exec();
}

生成如下所示的界面:

猜你喜欢

转载自blog.csdn.net/weixin_39568531/article/details/84643112