qt整个窗口上绘制矩形与在窗口的子控件上绘制矩形

引言

创建一个基于QDialog的项目,自动生成ui文件,此时再添加新文件,创建一个基于QWidget的ui类,此类具有自定义标题栏,让该自定义类显示在窗口Dialog上,一开始具有红色的边框线,且四角围绕四个矩形,点击中间的自定义窗口时,窗口的边框线由黄色实线变为蓝色实线,再点击变为红色虚线,再点击变为蓝色实现,再点击红色虚线等等。此类是为了区分在整个窗口上绘制矩形与在窗口的子控件上绘制矩形的不同。

效果

以上就可以实现下面的效果:
程序刚开始运行:
在这里插入图片描述
点击中间的窗口后:
在这里插入图片描述
再点击后的效果:
在这里插入图片描述

项目的结构:

在这里插入图片描述

示例

下面是上述示例的代码。创建基于QDialog的项目,不去掉ui文件,自动生成ui文件,然后添加新文件基于QWidget类,在生成的QWidget类的ui文件中拖入其它控件,QWidget类的ui文件结构如下图:
在这里插入图片描述
除了widget_3控件栅格布局的上下左右边框设置了边距,所有布局之间的距离都为0。
ui文件如下:
在这里插入图片描述
当然上谜案直接设置了控件widget,widget_2以及label的样式。
下面是完整的代码:
自定义窗口类的代码。
form.h

#ifndef FORM_H
#define FORM_H

#include <QWidget>

namespace Ui {
class Form;
}

class Form : public QWidget
{
    Q_OBJECT

public:
    explicit Form(QWidget *parent = nullptr);
    ~Form();

protected:
    bool eventFilter(QObject *watched, QEvent *event);//在子控件上绘制边框
    void paintBorder(QWidget *widget);//绘制窗口的边框为其它颜色
    void paintEvent(QPaintEvent *event);//初始的时候绘制窗口的整体边框色
    void mousePressEvent(QMouseEvent *event);//点击鼠标的时候窗口微移,下次点击窗口复位
private:
    Ui::Form *ui;
    bool        m_isNudge;//窗口是否微移
    bool        m_isPress;//是否点击了子控件窗口
};

#endif // FORM_H

form.cpp

#include "form.h"
#include "ui_form.h"
#include <QPainter>
#include <QPen>
#include <QMouseEvent>

Form::Form(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form)
{
    ui->setupUi(this);

    m_isNudge = false;
    m_isPress = false;
    ui->widget_3->installEventFilter(this);//安装事件过滤器
}

Form::~Form()
{
    delete ui;
}

bool Form::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == ui->widget_3 && event->type() == QEvent::Paint) {
        paintBorder(ui->widget_3);//没有触发重绘事件,所以画笔没有被激活
        return true;
    }
    return false;
}

void Form::paintBorder(QWidget *widget)
{
    if (!m_isPress) {
        return ;
    }
    QPainter painter(widget);
    QPen pen;
    QColor color;
    if (m_isNudge) {
        QColor cl(Qt::red);
        color = cl;
        pen.setStyle(Qt::DashDotLine);
    }else {
        QColor cl(Qt::darkBlue);
        color = cl;
        pen.setStyle(Qt::SolidLine);
    }

    pen.setColor(color);
    pen.setWidth(6);
    painter.setPen(pen);
    QRect rect = this->rect();
    painter.setRenderHint(QPainter::Antialiasing);
    painter.drawRect(rect.x(),rect.y(),rect.width(),rect.height());
}

void Form::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    QPen pen;
    pen.setWidth(6);
    pen.setColor(QColor(Qt::yellow));
    painter.setPen(pen);
    painter.drawRect(ui->widget_3->x(),ui->widget_3->y(),ui->widget_3->width(),ui->widget_3->height());
}

void Form::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_isPress = true;
        if (m_isNudge) {
            move(geometry().x() + 1,geometry().y() + 1);//通过移动触发重绘函数
            m_isNudge = false;
        }else {
            move(geometry().x() - 1,geometry().y() - 1);
            m_isNudge = true;
        }
    }
}

Dialog类的代码:
dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include "form.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

protected:
    void initChildControl();//初始化子控件
    void paintEvent(QPaintEvent *event);//绘制矩形
private:
    Ui::Dialog *ui;
    Form            *m_form;//子窗口
    QVector<QRect>  m_rectVec;//保存四个角的矩形
};
#endif // DIALOG_H

dialog,cpp

#include "dialog.h"
#include "ui_dialog.h"
#include <QPainter>
#include <QPen>
#include <QLabel>

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    initChildControl();
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::initChildControl()
{
    m_form = new Form(this);
    m_form->setGeometry(width() / 4,height() / 4 - 20,m_form->width(),m_form->height());
    //初始化窗口上四个角上的矩形
    QRect rect1(2,2,180,180);
    QRect rect2(width()-182,2,180,180);
    QRect rect3(2,height()-182,180,180);
    QRect rect4(width()-182,height()-182,180,180);
    m_rectVec.append(rect1);
    m_rectVec.append(rect2);
    m_rectVec.append(rect3);
    m_rectVec.append(rect4);
}

void Dialog::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QPen pen;
    pen.setWidth(4);
    pen.setColor(QColor(85,85,255,255));
    painter.setPen(pen);
    painter.drawRects(m_rectVec);
}

main.cpp

#include "dialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

总结

在整个窗口上绘制矩形,需要重写paintEvent函数,在该函数中实现绘制矩形;在窗口的子控件上绘制矩形,需要在改类的构造函数中给该绘图的子控件安装事件过滤器,然后重写事件过滤函数,在该子控件的相应事件下实现绘制矩形。注意安装事件过滤器。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肩上风骋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值