qt实现自定义标题栏的widget

实现思路:新建类MyWidget,继承Widget。

新建两个widget,titilewidget、centerwidget分别用于放置标题栏和其他内容。

在titlewidget里边添加图标、标题、最小化、最大化、关闭按钮

........

效果

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H
#pragma execution_character_set("UTF-8")
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


class MyWidget: public QWidget
{
    Q_OBJECT
private:
    QWidget *titleWidget;//标题栏Widget
    QToolButton *iconButton;//图标
    QPushButton *closeButton;//关闭按钮
    QPushButton *maxButton;//最大化按钮
    QPushButton *minButton;//最小化按钮
    QLabel *titleLabel;//标题label
    QRect winRect;//窗口位置
    bool m_ismaxed;//窗口是否最大化
    QPoint m_leftDownp;//左键按下的位置
    QPoint m_leftDownMapp;//左键按下时全局位置
    bool m_isleftClicked;//左键是否按下
    enum
    {
        Left,
        Right,
        Up,
        Bottom,
        LeftUp,
        RightUp,
        LeftBottom,
        RightBottom,
        Center
    };
    bool ApproximatelyEqual(const int a, const int b, int persion)
    {
        return abs(a-b) < persion ? true : false;
    }

protected:
    void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
    bool event(QEvent *event) Q_DECL_OVERRIDE;
    int GetMouseWidgetPos(QPoint p);//获取鼠标所在位置
    void setCursorShape(int CalPos);//设置鼠标样式

private:
    void InitializationWidget();//窗口初始化
    void ShowMaxSize();//窗口最大化
    void ShowNormalSize();//窗口非最大化

private slots:
    void WinNormalMaxChange();//窗口最大化最小化改变函数

public:
    QWidget *centerWidget;//中心widget,可操作空间
    MyWidget(QWidget *parent = nullptr);
    void SetWinTitle(QString title);//设置窗口标题
    void SetWinIcon(QIcon icon);//设置窗口图标
    void SetWinIcon(QImage img);
    void SetColor(uint r, uint g, uint b);//设置窗口颜色
};

#endif // MYWIDGET_H

MyWidget.cpp

#include "MyWidget.h"
#include 

MyWidget::MyWidget(QWidget *parent)
{
    setWindowFlags (Qt::FramelessWindowHint);
    this->resize(1200, 1000);
    m_ismaxed = 0;
    m_isleftClicked = 0;
    InitializationWidget();
    connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(minButton, SIGNAL(clicked()), this, SLOT(showMinimized()));
    connect(maxButton, SIGNAL(clicked()), this, SLOT(WinNormalMaxChange()));
    setAttribute(Qt::WA_Hover, true);
}


void MyWidget::InitializationWidget()
{
    titleWidget = new QWidget();
    titleWidget->setStyleSheet("background-color:white;");
    titleWidget->resize(1200, 40);
    centerWidget = new QWidget();
    iconButton = new QToolButton();
    iconButton->setFixedSize(40, 40);
    iconButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
    enum QStyle::StandardPixmap Icon = (enum QStyle::StandardPixmap) 0;
    iconButton->setIcon(QApplication::style()->standardIcon(Icon));
    iconButton->setStyleSheet("background:transparent");
    titleLabel = new QLabel("MyWidget");
    titleLabel->setStyleSheet("background:transparent;font-size:18px;border-width:0px");
    closeButton = new QPushButton("");
    maxButton = new QPushButton("");
    minButton = new QPushButton("⎯");
    closeButton->setFixedSize(60, 40);
    minButton->setFixedSize(60, 40);
    maxButton->setFixedSize(60, 40);
    minButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
                             "QPushButton:hover{background-color:rgb(229, 229, 229);}");
    closeButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
                               "QPushButton:hover{background-color:rgb(232, 17, 35);color:white;}");
    maxButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
                             "QPushButton:hover{background-color:rgb(229, 229, 229);}");
    //标题widget里边加东西
    QSpacerItem *verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
    QHBoxLayout *hboxlayout = new QHBoxLayout();
    hboxlayout->addWidget(iconButton);
    hboxlayout->addWidget(titleLabel);
    hboxlayout->addItem(verticalSpacer);
    hboxlayout->addWidget(minButton);
    hboxlayout->addWidget(maxButton);
    hboxlayout->addWidget(closeButton);
    hboxlayout->setSpacing(0);
    hboxlayout->setContentsMargins(0,0,0,0);
    titleWidget->setLayout(hboxlayout);
    //设置标题widget与中心widget布局
    QVBoxLayout *vboxlayout = new QVBoxLayout();
    vboxlayout->addWidget(titleWidget, 1);
    vboxlayout->addWidget(centerWidget, 100);
    vboxlayout->setSpacing(0);
    vboxlayout->setContentsMargins(0,0,0,0);
    this->setLayout(vboxlayout);
}


void MyWidget::WinNormalMaxChange()
{
    if (m_ismaxed)
    {
        ShowNormalSize();
    }
    else
    {
        ShowMaxSize();
    }
}


void MyWidget::ShowMaxSize()
{
    winRect = this->geometry();
    QRect trect = QApplication::desktop()->screenGeometry();
    this->setGeometry(trect);
    maxButton->setText("");
    m_ismaxed = 1;
}


void MyWidget::ShowNormalSize()
{
    this->setGeometry(winRect);
    maxButton->setText("");
    m_ismaxed = 0;
}


void MyWidget::mousePressEvent(QMouseEvent *event)
{
    //左键拖动窗口移动、左键控制移动
    if (event->button() == Qt::LeftButton)
    {
        //为了拖动
        m_leftDownp = event->globalPos()-pos();
        //为了缩放
        m_leftDownMapp = event->globalPos();
        m_isleftClicked = 1;
    }
    QWidget::mousePressEvent(event);
}


void MyWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    // 左键双击最大化
    if (event->button() == Qt::LeftButton && titleWidget->geometry().contains(this->mapFromGlobal(QCursor::pos())))
    {
        if (m_ismaxed)
        {
            ShowNormalSize();
        }
        else
        {
            ShowMaxSize();
        }
    }
    QWidget::mouseDoubleClickEvent(event);
}


void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        m_isleftClicked = 0;
    }
}


void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (m_isleftClicked)
    {
        if (titleWidget->geometry().contains(this->mapFromGlobal(QCursor::pos())))
        {
            //执行移动
            this->move(event->globalPos() - m_leftDownp);
        }
        else
        {
            //执行缩放
            QPoint ptMoveSize = event->globalPos() - m_leftDownMapp;
            int CalPos = GetMouseWidgetPos(event->globalPos());
            QRect rect = geometry();
            switch(CalPos)
            {
            case LeftUp:
                rect.setTopLeft(winRect.topLeft()+ptMoveSize);
                break;
            case Up:
                rect.setTop(winRect.top()+ptMoveSize.y());
                break;
            case RightUp:
                rect.setTopRight(winRect.topRight()+ptMoveSize);
                break;
            case Left:
                rect.setLeft(winRect.left()+ptMoveSize.x());
                break;
            case Right:
                rect.setRight(winRect.right()+ptMoveSize.x());
                break;
            case LeftBottom:
                rect.setBottomLeft(winRect.bottomLeft()+ptMoveSize);
                break;
            case Bottom:
                rect.setBottom(winRect.bottom()+ptMoveSize.y());
                break;
            case RightBottom:
                rect.setBottomRight(winRect.bottomRight()+ptMoveSize);
                break;
            default:
                break;
            }
            setGeometry(rect);
        }
        if (!m_ismaxed)
            winRect = this->geometry();
    }
    QWidget::mouseMoveEvent(event);
}


bool MyWidget::event(QEvent *event)
{
    //更改鼠标样式
    if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave || event->type() == QEvent::HoverMove)
    {
        QHoverEvent* pHoverEvent = static_cast(event);
        QPoint cursorPos = mapToGlobal(pHoverEvent->pos());
        if(!m_isleftClicked)
        {
            int CalPos = GetMouseWidgetPos(cursorPos);
            setCursorShape(CalPos);
        }
    }
    return QWidget::event(event);
}


int MyWidget::GetMouseWidgetPos(QPoint p)
{
    QRect rect = geometry();
    int minx = rect.x();
    int miny = rect.y();
    int maxy = rect.y()+rect.height();
    int maxx = rect.x()+rect.width();
    int x = p.x();
    int y = p.y();
    int persion = 5;
    if (ApproximatelyEqual(x, minx, persion) && ApproximatelyEqual(y, miny, persion))
        return LeftUp;
    else if (ApproximatelyEqual(x, minx, persion))
        return Left;
    else if (ApproximatelyEqual(y, miny, persion))
        return Up;
    else if (ApproximatelyEqual(x, maxx, persion) && ApproximatelyEqual(y, maxy, persion))
        return RightBottom;
    else if (ApproximatelyEqual(x, maxx, persion))
        return Right;
    else if (ApproximatelyEqual(y, maxy, persion))
        return Bottom;
    else if (ApproximatelyEqual(x, minx, persion) && ApproximatelyEqual(y, maxy, persion))
        return LeftBottom;
    else if (ApproximatelyEqual(x, maxx, persion) && ApproximatelyEqual(y, miny, persion))
        return RightUp;
    else
        return Center;
}


void MyWidget::setCursorShape(int CalPos)
{
    Qt::CursorShape cursor;
    switch(CalPos)
    {
    case LeftUp:
    case RightBottom:
        cursor = Qt::SizeFDiagCursor;
        break;
    case RightUp:
    case LeftBottom:
        cursor = Qt::SizeBDiagCursor;
        break;
    case Up:
    case Bottom:
        cursor = Qt::SizeVerCursor;
        break;
    case Left:
    case Right:
        cursor = Qt::SizeHorCursor;
        break;
    default:
        cursor = Qt::ArrowCursor;
        break;
    }
    setCursor(cursor);
}


void MyWidget::SetWinTitle(QString title)
{
    titleLabel->setText(title);
}


void MyWidget::SetWinIcon(QIcon icon)
{
    iconButton->setIcon(icon);
}


void MyWidget::SetWinIcon(QImage img)
{
    QPixmap pmap = QPixmap::fromImage(img);
    QIcon icon(pmap.scaled(iconButton->width(), iconButton->height()));
    iconButton->setIcon(icon);
}


void MyWidget::SetColor(uint r, uint g, uint b)
{
    QString str = "background-color:rgb(" +  QString::number(r) + "," + QString::number(g) + "," + QString::number(b) + ");";
    titleWidget->setStyleSheet(str);
}

调用——main.cpp

#include "MyWidget.h"
#include 




int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    MyWidget w;
    w.SetWinTitle("test");
    QImage img("D:/Postgraduate/something/QCoomapTest/QCoomapTest/gui-icon.png");
    w.SetWinIcon(img);
    w.SetColor(18, 55, 107);
    w.show();
    return a.exec();
}

你可能感兴趣的:(qt,开发语言)