文章目录
- 一、效果示例图
- 1.效果演示图片
- 3.弹窗演示图片
- 二.问题描述
- 三、源码
- CFrame.h
- CFrame.cpp
- CMainWindow.h
- CMainWindow.cpp
- 总结
一、效果示例图
1.效果演示图片
3.弹窗演示图片
二.问题描述
(因为全是简单使用,毫无技巧,直接描述问题)
- 模糊效果:QGraphicsBlurEffect包含setBlurHints函数,其作用为设置模糊质量,但是更新它时我这边肉眼上是没有看出特别明显的效果,需考虑不同情况的状态。
- 阴影效果:使用QGraphicsDropShadowEffect时,当我作用到弹窗上,它不是作用在弹窗边缘之外,而是作用在弹窗边缘之内,所以需要为其预留部分空间显示阴影。
- 透明效果:文中是使用QLinearGradient设置其不透明蒙版,使用中我试图使用三种不同颜色操作蒙版但是失败;其次是我首次将其作用到弹窗中是有效的,但是二次过后就无效,这个我暂时没找到原因。
三、源码
CFrame.h
#ifndef CFRAME_H
#define CFRAME_H
#include <QObject>
#include <QFrame>
#include <QLabel>
#include <QHBoxLayout>
class CFrame : public QFrame
{
Q_OBJECT
public:
explicit CFrame(QWidget *parent = nullptr);
~CFrame();
/**
* @brief setStyleSheet 重写样式设置
* @param style 样式文本
*/
void setStyleSheet(const QString &style);
// QWidget interface
protected:
/**
* @brief keyReleaseEvent 键盘释放事件
* @param event 事件对象
*/
void keyReleaseEvent(QKeyEvent *event);
/**
* @brief mousePressEvent 鼠标按下事件
* @param event 事件对象
*/
void mousePressEvent(QMouseEvent *event);
/**
* @brief mouseMoveEvent 鼠标移动事件
* @param event 事件对象
*/
void mouseMoveEvent(QMouseEvent *event);
private:
QPoint m_globalMousePos; // 全局鼠标位置
QPoint m_globalWindowPos; // 全局窗口位置
QHBoxLayout *m_layout; // 水平布局器对象
QLabel *m_label; // 图片样式label
};
#endif // CFRAME_H
CFrame.cpp
#include "CFrame.h"
#include <QKeyEvent>
CFrame::CFrame(QWidget *parent) : QFrame(parent)
{
this->setToolTip(u8"按任意键关闭窗口");
this->setWindowFlag(Qt::FramelessWindowHint, true);
// 创建水平布局器对象
m_layout = new QHBoxLayout;
m_layout->setMargin(10);
// 创建图片显示label
m_label = new QLabel;
m_layout->addWidget(m_label);
// 将布局器设置到当前类中
this->setLayout(m_layout);
}
CFrame::~CFrame()
{
delete m_layout;
delete m_label;
}
void CFrame::setStyleSheet(const QString &style)
{
// 样式设置到label上
m_label->setStyleSheet(style);
}
void CFrame::keyReleaseEvent(QKeyEvent *event)
{
// 任意键释放都关闭窗口
this->close();
}
void CFrame::mousePressEvent(QMouseEvent *event)
{
// 获取鼠标全局位置
m_globalMousePos = event->globalPos();
// 获取窗口左上角位置
m_globalWindowPos = this->frameGeometry().topLeft();
}
void CFrame::mouseMoveEvent(QMouseEvent *event)
{
//获得鼠标移动的距离
QPoint distance = event->globalPos() - m_globalMousePos;
//改变窗口的位置
this->move(m_globalWindowPos + distance);
}
CMainWindow.h
#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H
#include "CFrame.h"
#include <QGraphicsBlurEffect>
#include <QGraphicsColorizeEffect>
#include <QGraphicsDropShadowEffect>
#include <QGraphicsOpacityEffect>
#include <QMainWindow>
#include <QLinearGradient>
QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE
class CMainWindow : public QMainWindow
{
Q_OBJECT
public:
CMainWindow(QWidget *parent = nullptr);
~CMainWindow();
private:
void connectSigSlot();
/**
* @brief getCurTypeEffect 获取效果对象
* @param id 效果id
* @return 效果对象指针
*/
QGraphicsEffect *getCurTypeEffect(int id);
private slots:
/**
* @brief on_buttonGroup_buttonClicked 单选按钮组点击槽函数
* @param id 点击按钮id
*/
void on_buttonGroup_buttonClicked(int id);
/**
* @brief on_doubleSpinValueChanged 浮点微调框槽函数
* @param arg1 调整值
*/
void on_doubleSpinValueChanged(double arg1);
/**
* @brief on_spinValueChanged 整型微调框槽函数
* @param arg1 调整值
*/
void on_spinValueChanged(int arg1);
/**
* @brief on_btnClicked 按钮点击槽函数
*/
void on_btnClicked();
/**
* @brief on_btnSelImg_clicked 图片选择槽函数
*/
void on_btnSelImg_clicked();
/**
* @brief on_btnBecomeDlg_clicked 弹窗按钮槽函数
*/
void on_btnBecomeDlg_clicked();
// QWidget interface
protected:
/**
* @brief closeEvent 关闭事件
* @param event 时间对象
*/
void closeEvent(QCloseEvent *event);
private:
Ui::CMainWindow *ui;
QLinearGradient m_linearGradient; // 透明效果的颜色梯度
CFrame *m_dlgFrame; // 弹窗对象
};
#endif // CMAINWINDOW_H
CMainWindow.cpp
#include "CMainWindow.h"
#include "ui_CMainWindow.h"
#include <QDebug>
#include <QKeyEvent>
#include <QFileDialog>
#include <QColorDialog>
CMainWindow::CMainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::CMainWindow)
{
ui->setupUi(this);
// 创建弹窗对象
m_dlgFrame = new CFrame;
// 设置单选按钮id值
ui->buttonGroup->setId(ui->checkBoxNoEffect, 0);
ui->buttonGroup->setId(ui->checkBoxBlurEffect, 1);
ui->buttonGroup->setId(ui->checkBoxColorEffect, 2);
ui->buttonGroup->setId(ui->checkBoxShadowEffect, 3);
ui->buttonGroup->setId(ui->checkBoxOpacityEffect, 4);
// 线性渐变对象颜色位置赋值
m_linearGradient.setColorAt(0, Qt::transparent);
m_linearGradient.setColorAt(0.5, Qt::black);
m_linearGradient.setColorAt(1, Qt::transparent);
connectSigSlot();
}
CMainWindow::~CMainWindow()
{
delete m_dlgFrame;
delete ui;
}
void CMainWindow::connectSigSlot()
{
// 链接浮点型数值框信号槽
connect(ui->doubleSpinColorStrength, SIGNAL(valueChanged(double)), this, SLOT(on_doubleSpinValueChanged(double)));
connect(ui->doubleSpinBoxOpacity, SIGNAL(valueChanged(double)), this, SLOT(on_doubleSpinValueChanged(double)));
// 链接整型数值框信号槽
connect(ui->spinBoxBulrRadius, SIGNAL(valueChanged(int)), this, SLOT(on_spinValueChanged(int)));
connect(ui->spinBoxHorOffset, SIGNAL(valueChanged(int)), this, SLOT(on_spinValueChanged(int)));
connect(ui->spinBoxVerOffset, SIGNAL(valueChanged(int)), this, SLOT(on_spinValueChanged(int)));
connect(ui->spinBoxShadowBlurRadius, SIGNAL(valueChanged(int)), this, SLOT(on_spinValueChanged(int)));
// 链接按钮信号槽
connect(ui->btnColorSel, &QPushButton::clicked, this, &CMainWindow::on_btnClicked);
connect(ui->btnShadowColorSel, &QPushButton::clicked, this, &CMainWindow::on_btnClicked);
}
QGraphicsEffect *CMainWindow::getCurTypeEffect(int id)
{
QGraphicsEffect *effectTmp = Q_NULLPTR;
//! 根据ID创建效果对象,并将对应的效果之更新到对象中
switch (id) {
case 1:
{
QGraphicsBlurEffect *blurEffect = new QGraphicsBlurEffect; // 模糊效果
// 设置颜模糊半径
blurEffect->setBlurRadius(ui->spinBoxBulrRadius->value());
effectTmp = blurEffect;
break;
}
case 2:
{
QGraphicsColorizeEffect *colorEffect = new QGraphicsColorizeEffect; // 颜色效果
// 设置颜色强度
colorEffect->setStrength(ui->doubleSpinColorStrength->value());
// 设置颜色
colorEffect->setColor(ui->btnColorSel->palette().color(QPalette::Button));
effectTmp = colorEffect;
break;
}
case 3:
{
QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect; // 阴影效果
shadowEffect->setColor(ui->btnShadowColorSel->palette().color(QPalette::Button)); // 阴影颜色
shadowEffect->setOffset(ui->spinBoxHorOffset->value(), ui->spinBoxVerOffset->value()); // 阴影偏移度
shadowEffect->setBlurRadius(ui->spinBoxBulrRadius->value()); // 模糊半径
effectTmp = shadowEffect;
break;
}
case 4:
{
QGraphicsOpacityEffect *opacityEffect = new QGraphicsOpacityEffect;
opacityEffect->setOpacity(ui->doubleSpinBoxOpacity->value()); // 透明度
m_linearGradient.setStart(ui->label->geometry().topLeft()); //起始位置
m_linearGradient.setFinalStop(ui->label->geometry().bottomLeft()); // 结束位置
opacityEffect->setOpacityMask(m_linearGradient);
effectTmp = opacityEffect;
break;
}
default:
{
break;
}
}
return effectTmp;
}
void CMainWindow::on_buttonGroup_buttonClicked(int id)
{
// 更新栈窗口
ui->stackedWidget->setCurrentIndex(id);
// 更新控件效果
ui->label->setGraphicsEffect(getCurTypeEffect(id));
}
void CMainWindow::on_doubleSpinValueChanged(double arg)
{
//! 获取发送者类型属性值
//! 不同值做不同操作
switch (sender()->property("Type").toInt())
{
case 2:
{
// 设置颜色强度
dynamic_cast<QGraphicsColorizeEffect*>(ui->label->graphicsEffect())->setStrength(arg);
break;
}
case 4:
{
// 设置透明度
dynamic_cast<QGraphicsOpacityEffect*>(ui->label->graphicsEffect())->setOpacity(arg);
break;
}
default:
break;
}
}
void CMainWindow::on_spinValueChanged(int arg)
{
//! 获取发送者类型属性值
//! 不同值做不同操作
switch (sender()->property("Type").toInt())
{
case 1:
{
// 设置颜模糊半径
dynamic_cast<QGraphicsBlurEffect*>(ui->label->graphicsEffect())->setBlurRadius(arg);
break;
}
case 3:
{
int flag = sender()->property("WhatThis").toInt();
if(0 == flag)
{
// 设置颜模糊半径
dynamic_cast<QGraphicsDropShadowEffect*>(ui->label->graphicsEffect())->setBlurRadius(arg);
}
else if(1 == flag)
{
// 设置垂直偏移
dynamic_cast<QGraphicsDropShadowEffect*>(ui->label->graphicsEffect())->setYOffset(arg);
}
else
{
// 设置水平偏移
dynamic_cast<QGraphicsDropShadowEffect*>(ui->label->graphicsEffect())->setXOffset(arg);
}
break;
}
default:
break;
}
}
void CMainWindow::on_btnClicked()
{
QPushButton *btn = dynamic_cast<QPushButton *>(sender());
// 获取按钮进入的palette对象
QPalette palette(btn->palette());
// 颜色对象先赋值为当前按钮颜色(防止重新获取颜色时拿到失效颜色)
QColor color = palette.color(QPalette::Button);
// 然后重新获取颜色
color = QColorDialog::getColor();
if(!color.isValid())
{
return;
}
//! 获取发送者类型属性值
//! 不同值做不同操作
switch (btn->property("Type").toInt())
{
case 2:
{
// 设置颜色
dynamic_cast<QGraphicsColorizeEffect*>(ui->label->graphicsEffect())->setColor(color);
break;
}
case 3:
{
// 设置阴影颜色
dynamic_cast<QGraphicsDropShadowEffect*>(ui->label->graphicsEffect())->setColor(color);
break;
}
default:
break;
}
// 更新调色板对象按钮颜色
palette.setColor(QPalette::Button, color);
btn->setPalette(palette);
btn->setFlat(true); // 设置按钮扁平化
btn->setAutoFillBackground(true); // 设置自动填充背景
}
void CMainWindow::on_btnSelImg_clicked()
{
// 获取图片
QString fileName = QFileDialog::getOpenFileName(this, u8"选择图片", "./", "*.png *.jpg *.svg");
// 为空返回
if(fileName.isEmpty())
{
return;
}
// 通过样式设置图片
ui->label->setStyleSheet(QString("border-image:url(%1)").arg(fileName));
}
void CMainWindow::on_btnBecomeDlg_clicked()
{
// 设置大小为本类的label(图片显示控件)大小
m_dlgFrame->setFixedSize(ui->label->size());
// 当前样式图片更新到弹窗label中
m_dlgFrame->setStyleSheet(ui->label->styleSheet());
// 获取当前属性效果并设置
m_dlgFrame->setGraphicsEffect(getCurTypeEffect(ui->buttonGroup->checkedId()));
// 显示弹窗
m_dlgFrame->show();
}
void CMainWindow::closeEvent(QCloseEvent *event)
{
// 当弹窗未关闭时进入关闭
if(m_dlgFrame->isVisible())
{
m_dlgFrame->close();
}
}
总结
效果使用较为简单,因此暂无强调;文中存在一些问题,后期有解决会更新(要是有大佬指点更好啦)。
友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)
注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除