Qt笔记之使用设计器自定义窗口标题栏

1.在窗口显示之前,设置WindowFlagsFramelessWindowHint,以产生一个没有边界的窗口

例如

Widget::Widget(QWidget *parent) :
    QWidget(parent, Qt::FramelessWindowHint),  //在此设置WindowFlags
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //setWindowFlags(Qt::FramelessWindowHint);  或在构造函数体中设置
}

2.在设计器中,拖一个Widget到窗口上。为方便描述,我命名此Widget为titleBarWidget

将titleBarWidget的minimumSize->height改为30,以固定标题栏高度

更改titleBarWidget的样式表为background-color: #12B7F5;

再拖一个Vertical Spacer到窗口上,并设置窗口为竖直布局

去除标题栏边距,将layoutLeftMargin、layoutTopMargin和layoutRightMargin都设置为0

效果如图

3.为了能拖动标题栏移动窗口,我们定义一个类,如下

TitleBarWidget.h

#ifndef TITLEBARWIDGET_H
#define TITLEBARWIDGET_H

#include <QWidget>

class TitleBarWidget : public QWidget
{
    Q_OBJECT
public:
    explicit TitleBarWidget(QWidget *parent = nullptr);
protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
private:
    int differenceX, differenceY;
};

#endif // TITLEBARWIDGET_H

TitleBarWidget.cpp

#include "TitleBarWidget.h"
#include <QMouseEvent>

TitleBarWidget::TitleBarWidget(QWidget *parent) : QWidget(parent) { }

void TitleBarWidget::mousePressEvent(QMouseEvent *event)
{
    QWidget *parentWidget = static_cast<QWidget *>(parent());
    differenceX = event->globalX() - parentWidget->x();
    differenceY = event->globalY() - parentWidget->y();
}

void TitleBarWidget::mouseMoveEvent(QMouseEvent *event)
{
    int x = event->globalX() - differenceX;
    int y = event->globalY() - differenceY;
    QWidget *parentWidget = static_cast<QWidget *>(parent());
    parentWidget->move(x, y);
}

将titleBarWidget提升为TitleBarWidget,就能实现拖动标题栏移动窗口了

4.然而问题来了,titleBarWidget的样式表失效了

为解决这个问题,需要重写QWidget中的paintEvent,代码如下

void TitleBarWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QStyleOption option;
    option.init(this);
    QStylePainter painter(this);
    painter.drawPrimitive(QStyle::PE_Widget, option);
}
原文地址:https://www.cnblogs.com/buyishi/p/10306906.html