【QT入门】 无边框窗口设计之实现圆角窗口

本文介绍了如何在QT中实现无边框窗口的自定义标题栏,包括拖动和拉伸效果,以及两种方法实现圆角窗口:一是通过重写paintEvent绘制,二是使用QStyleOption和drawPrimitive。作者详细展示了代码示例和两种方法的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

往期回顾:

【QT入门】对无边框窗口自定义标题栏并实现拖动和拉伸效果-CSDN博客

【QT入门】 自定义标题栏界面qss美化+按钮功能实现-CSDN博客

【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客

 【QT入门】 无边框窗口设计之实现圆角窗口

我们实际用到的很多窗口,其实都是带圆角的,所以这个知识点还是很有必要知道,有两种方法都可以实现圆角窗口,两个方法都需要重写void paintEvent(QPaintEvent* event) override。

一、最终效果

这里的效果用的是第二种,可以看到,左上角和右下角设置为了圆角,通过重写paintEvent方法我们可以实现精准控制哪个角设置为圆角,圆角半径为多大。
而如果是第一种,就是四个角都是圆角。

二、用Qt绘图框架绘制

1、初始化界面

void radius::initUIshang()
{
    resize(600, 400);

    setAttribute(Qt::WA_TranslucentBackground);  //设置窗口背景透明
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);  //去掉窗口边框
}

 主要是先设置窗口背景透明和去掉窗口边框,这个常规操作了

2、重写paintEvent方法

void radius::paintEvent(QPaintEvent * event)
{
    QPainter painter(this);// 创建一个QPainter对象并指定绘制设备为this,即当前窗口
    painter.setRenderHint(QPainter::Antialiasing);  // 设置绘制选项为反锯齿,使绘制的图形边缘更加平滑
    painter.setBrush(QBrush(QColor(255, 255, 255)));//// 设置画刷颜色,这里为白色
    painter.setPen(Qt::transparent);//// 设置画笔颜色为透明,即不绘制边框线
    QRect rect = this->rect();//// 获取当前窗口的矩形区域
    painter.drawRoundedRect(rect, 15, 15);  // 绘制一个带有圆角的矩形窗口,圆角半径为15px,如果把窗口设置成正方形,圆角半径设大,就会变成一个圆了

}

 创建对象,设置了反锯齿效果,设置画笔画刷颜色等,最重要的,drawRoundedRect方法设置圆角半径。

2.1drawRoundedRect
painter.drawRoundedRect(rect, 15, 15) 

 这个方法三个参数:

矩形的位置和大小(rect)定义了矩形窗口的位置和大小,通常是一个矩形的边界框。
水平方向的圆角半径(15)定义水平方向的圆角半径,控制矩形窗口的左上角和右上角的圆角大小。
垂直方向的圆角半径(15)定义垂直方向的圆角半径,控制矩形窗口的左上角和左下角的圆角大小。

此时右下角的圆角大小会与左上角的圆角大小相同,而右上角和左下角的圆角大小也会相同。

我们这里将这两个圆角半径设置为相同的值,都为15,那么绘制的矩形窗口将具有相同大小的圆角,使得整个窗口看起来更加圆润。

 当圆角半径的值设置得足够大时,如果矩形窗口的宽度和高度相等,就会变成一个圆形窗口,因为圆角的半径大于矩形的宽度或高度,导致整个矩形都被圆角所覆盖,从而呈现出一个圆形。

三、用Qt绘图风格绘制 

1、初始化界面

void radius::initUIxia()
{
    setAttribute(Qt::WA_TranslucentBackground);  //设置窗口背景透明
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);  //去掉窗口边框

    //this->setStyleSheet("QWidget{background-color:#FFFFFF;border-radius:30px;}");
    this->setStyleSheet("QWidget{background-color:#FFFFFF;  \
        border-top-left-radius:15px;   \
        border-bottom-right-radius:15px; \
        }");
}

在初始化界面设置样式的时候,就可以指定哪个角设置为圆角,以及圆角半径大小。这里只设置了左上角和右下角。

左上角border-top-left-radius : 15px
右上角 border-top-right-radius: 15px;
左下角border-bottom-left-radius :5px;
右下角border-bottom-right-radius:5px;
border-radius的参数设置:
(1)可以只传一个参数,这样x, y方向的圆度是一样的,例如border-radius: 30px
(2)传两个参数  border-radius: 15px 20px  第一个参数设置X轴方向的半径,第二个参数设置Y轴方向的半径 

2、重写paintEvent方法

void radius::paintEvent(QPaintEvent*)
{
    QStyleOption opt;  // 创建一个QStyleOption对象
    opt.init(this);// 初始化QStyleOption对象,传入当前窗口指针
    QPainter p(this);// 创建一个QPainter对象,绘制设备为当前窗口

    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);// 使用当前窗口的绘图风格绘制小部件

}
 2.1QStyleOption

QStyleOption是Qt中用于传递样式选项的类,它在绘制控件时起着重要的作用。QStyleOption类提供了各种属性和方法,用于描述控件的外观和状态,以便样式系统能够正确地绘制控件。

其常见作用如下:

1、描述控件的状态QStyleOption可以描述控件的各种状态,如悬停、按下、选中等状态,以便样式系统能够根据状态来绘制控件。
2、传递控件的尺寸和位置QStyleOption可以包含控件的几何信息,如位置、大小、边界框等,以便样式系统能够根据几何信息来绘制控件。
3、传递控件的内容和文本QStyleOption可以包含控件的文本、图标等内容信息,以便样式系统能够在绘制时考虑内容的布局和显示。
4、传递用户定义的属性可以通过QStyleOption的扩展属性来传递自定义的属性信息,以便在绘制时能够根据这些属性做出相应的处理。
2.2drawPrimitive

drawPrimitive方法的四个参数也需要介绍一下(QStyle::PE_Widget, &opt, &p, this) 

1、QStyle::PrimitiveElement 类型的枚举值表示要绘制的元素类型

2、QStyleOption 类型的指针

表示绘制元素的选项
3、QPainter 类型的指针表示绘制的目标设备
4、QWidget 类型的指针表示与绘制相关联的小部件

从效果上来说,两个都是一样的,第二种方式可以实现更精细化的控制,因为四个角哪个用圆角哪个用平角都可以设置。

都看到这里了,点个赞再走呗朋友~

加油吧,预祝大家变得更强!

<think>好的,用户想了解如何在Qt实现边框圆角窗口。我需要先回忆一下相关的知识,确保自己记得正确的步骤和方法。 首先,用户提到了无边框窗口设计,所以应该想到设置窗口标志为FramelessWindowHint。这会去掉标题栏和边框,但需要自己处理窗口移动和关闭等功能。 接下来是圆角效果。通常的做法是使用样式表(QSS)来设置边框半径,但要注意的是,直接对主窗口应用border-radius可能不起作用,因为默认的窗口背景可能是空白。需要确保背景色或图片填充,使圆角可见。可能需要设置QWidget的background-color,并且在样式表中设置border-radius和overflow:hidden,以防止子组件超出圆角区域。 然后,可能要考虑阴影效果,因为无边框窗口通常没有阴影,看起来可能不够立体。可以使用QGraphicsDropShadowEffect来添加阴影,但要注意阴影会和圆角配合,可能需要调整偏移量和模糊半径。 另外,还要处理窗口的拖动功能。因为去除了标题栏,用户无法通过标题栏拖动窗口,所以需要在鼠标事件中自己实现拖动逻辑。比如在mousePressEvent和mouseMoveEvent中检测鼠标按下时的位置,然后移动窗口。 还有可能遇到的问题是,子控件或布局的边距,圆角可能会被覆盖,需要确保子控件适当内缩,或者设置父窗口的自动填充背景为true,避免背景穿透。 可能用户还会关心不同平台下的表现,比如Windows和macOS下阴影和圆角的差异,可能需要平台特定的调整。或者是否需要处理高DPI缩放,确保圆角在高分辨率下显示正确。 另外,用户可能需要示例代码来演示这些步骤,所以应该准备一个简单的例子,包括设置无边框、样式表圆角、阴影效果和拖动功能。同时要提醒注意事项,比如子控件不要超出圆角区域,可能需要设置mask,但使用样式表的border-radius通常更高效。 最后,检查是否有遗漏的部分,比如窗口的关闭按钮可能需要自定义,或者最小化、最大化按钮的实现。不过用户的问题主要集中在圆角窗口实现,可能不需要详细讲解按钮部分,但可以简要提及需要自己添加这些控件。 总结一下,回答的步骤应该是: 1. 设置窗口边框。 2. 应用样式表实现圆角。 3. 添加阴影效果。 4. 实现窗口拖动功能。 5. 注意事项和常见问题。</think>在 Qt实现边框圆角窗口需要结合**窗口属性设置**和**样式表(QSS)**,以下是详细步骤和注意事项: --- ### 1. 设置无边框窗口 ```cpp // 在构造函数中移除默认边框 setWindowFlags(Qt::FramelessWindowHint); // 确保背景透明(可选,视设计需求) setAttribute(Qt::WA_TranslucentBackground); ``` --- ### 2. 通过样式表实现圆角 ```cpp // 设置窗口主体的圆角样式(假设主窗口类名为 QWidget) setStyleSheet(R"( QWidget { background: #FFFFFF; /* 背景色 */ border-radius: 15px; /* 圆角半径 */ border: 2px solid #CCCCCC;/* 可选边框 */ } )"); ``` #### 关键点: - **子控件穿透问题**:如果子控件(如按钮)超出圆角区域,需设置 `QWidget { overflow: hidden; }`。 - **背景填充**:若未设置背景色,圆角可能不生效(透明区域显示直角)。 --- ### 3. 添加阴影效果(可选) ```cpp QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); shadow->setBlurRadius(20); // 阴影模糊半径 shadow->setColor(Qt::gray); // 阴影颜色 shadow->setOffset(0, 0); // 阴影偏移量 this->setGraphicsEffect(shadow); // 应用阴影 ``` --- ### 4. 实现窗口拖动功能 ```cpp // 重写鼠标事件实现拖动 void YourWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_dragPosition = event->globalPos() - frameGeometry().topLeft(); event->accept(); } } void YourWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { move(event->globalPos() - m_dragPosition); event->accept(); } } ``` --- ### 5. 完整代码示例 ```cpp class RoundedWindow : public QWidget { public: RoundedWindow(QWidget *parent = nullptr) : QWidget(parent) { setWindowFlags(Qt::FramelessWindowHint); setAttribute(Qt::WA_TranslucentBackground); // 设置圆角样式 setStyleSheet(R"( QWidget { background: #FFFFFF; border-radius: 15px; } )"); // 添加阴影 QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); shadow->setBlurRadius(20); shadow->setColor(Qt::gray); this->setGraphicsEffect(shadow); // 添加关闭按钮(示例) QPushButton *closeBtn = new QPushButton("×", this); connect(closeBtn, &QPushButton::clicked, this, &QWidget::close); } protected: void mousePressEvent(QMouseEvent *event) override { /* 拖动代码 */ } void mouseMoveEvent(QMouseEvent *event) override { /* 拖动代码 */ } private: QPoint m_dragPosition; }; ``` --- ### 常见问题 1. **圆角锯齿**:确保开启抗锯齿(默认启用),检查样式表是否正确应用。 2. **子控件直角溢出**:在布局中设置 `layout->setContentsMargins(5,5,5,5);` 留出边距。 3. **性能问题**:避免频繁重绘,复杂场景建议使用 `QPainterPath` 绘制自定义形状。 通过以上步骤,即可实现美观的无边框圆角窗口,适用于自定义弹窗、浮层等场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值