当前位置:   article > 正文

设置qwidget窗口在最前端_使用Qt实现超酷炫窗口特效

qt 如何使widget在表面上

Hello,大家好,今天给大家分享个比较有趣的小示例,按钮特效,具体效果如下图所示

 97fd02529225e4a53b298244fe8776ca.gif

下面,我们来看看它是如何实现的。

按钮特效,需要用到QWidget的方法:

void QWidget::setGraphicsEffect(QGraphicsEffect *effect)

QGraphicsEffect类是窗口特效的基类,基于该基类,Qt提供了四种便捷类: 

不加特效的正常图片

 c2b790d6d727ff5beece347d4ea96bff.png

1 QGraphicsBlurEffect //模糊特效

 7f0e039c82a1f8cf8c7143e14a47caa2.png

2 QGraphicsColorizeEffect //颜色特效 877ea8aed52e25fe3a925a0b58e4ac7f.png

3 QGraphicsOpacityEffect //透明度特效 3cee238e895a9b2060b888f6766d5bea.png

4 QGraphicsDropShadowEffect //阴影特效b957e773267d54031955bd0b75580bb1.png

示例中的按钮使用了阴影特效,其它特效用法类似。 

新建一个GUI工程,取名为SwitchButtonWidget ui界面为: db8dd94c0f6fc2f07476595cb6285583.png

按钮命名格式为“btn行号列号”,并且将这些QPushButton提升为MyButton,MyButton我们后面再定义。

使用这样的命名规则是为了当按下方向键(上下左右键)方便将焦点框切换到对应的按钮上

 097db2e039d64a578439cc1c2f59d31f.png

右键,修改样式表,修改窗口的样式为:

QPushButton {

border-radius: 4px;

border: none;

width: 35px;

height: 35px;

color: rgb(180, 0, 0);

font: bold 25px;

}

QPushButton:hover {

background: rgb(85, 85, 85);

}

QPushButton:pressed{

background: rgb(80, 80, 80);

}

QWidget {

border: 1px solid "#222222";

background-color: "#222222";

}

switchbuttonwidget.h

#ifndef SWITCHBUTTONWIDGET_H

#define SWITCHBUTTONWIDGET_H

#include <QtWidgets>

#include "controltable.h"

namespace Ui {

class SwitchButtonWidget;

}

class SwitchButtonWidget : public QWidget

{

Q_OBJECT

public:

explicit SwitchButtonWidget(QWidget *parent = 0);

~SwitchButtonWidget();

protected:

//重写实现按键事件

void keyPressEvent(QKeyEvent* e);

private:

void createTable();

private:

Ui::SwitchButtonWidget *ui;

ControlTable* table;

};

#endif // SWITCHBUTTONWIDGET_H

switchbuttonwidget.cpp

#include "switchbuttonwidget.h"

#include "ui_switchbuttonwidget.h"

SwitchButtonWidget::SwitchButtonWidget(QWidget *parent) :

QWidget(parent),

ui(new Ui::SwitchButtonWidget)

{

ui->setupUi(this);

createTable();

}

SwitchButtonWidget::~SwitchButtonWidget()

{

delete ui;

}

void SwitchButtonWidget::keyPressEvent(QKeyEvent *e)

{

int k = e->key();

switch (k)

{

case Qt::Key_Up:

{

table->toUp();

break;

}

case Qt::Key_Down:

{

table->toDown();

break;

}

case Qt::Key_Left:

{

table->toLeft();

break;

}

case Qt::Key_Right:

{

table->toRight();

break;

}

}

}

void SwitchButtonWidget::createTable()

{

QList<ControlList> tmpTable;

ControlList row0;

ControlList row1;

ControlList row2;

ControlList row3;

row0 << ui->btn_0_0 << ui->btn_0_1 << ui->btn_0_2;

row1 << ui->btn_1_0 << ui->btn_1_1 << ui->btn_1_2;

row2 << ui->btn_2_0 << ui->btn_2_1 << ui->btn_2_2;

row3 << ui->btn_3_0 << ui->btn_3_1 << ui->btn_3_2;

tmpTable << row0 << row1 << row2 << row3;

table = new ControlTable(this);

table->setTable(tmpTable);

}

下面是controltable的声明,具体思路已经写在注释里了,这里就不多解释了 

controltable.h

#ifndef CONTROLTABLE_H

#define CONTROLTABLE_H

#include <QtWidgets>

typedef QList<QWidget*> ControlList;

class ControlTable: public QObject

{

Q_OBJECT

public:

//注意parent不能为空

ControlTable(QWidget *parent);

void setTable(const QList<ControlList>& t);

//按钮焦点上移

void toUp();

//按钮焦点下移

void toDown();

//按钮焦点左移

void toLeft();

//按钮焦点右移

void toRight();

signals:

void controlSwitched(QWidget* oldControl, QWidget* newControl);

private:

//返回按钮表格第r行所有按钮列表

ControlList rowControls(int r);

//返回按钮表格第c列所有按钮列表

ControlList colControls(int c);

//获取控件行号

int row(QWidget* control);

//获取控件列号

int col(QWidget* control);

//判断行列是否都有效

bool isValid(int r, int c);

//按钮表格最大行数

int rowCount();

//选中btn

void selectControl(QWidget* control);

//返回btnList第index索引位置的后一个按钮

//如果btnList只有一个按钮,则返回按钮本身

QWidget* nextControl(const ControlList& controlList, int index);

//返回btnList第index索引位置的前一个按钮

//如果btnList只有一个按钮,则返回按钮本身

QWidget* preControl(const ControlList& controlList, int index);

//设置特效颜色阴影边框

void setFrame(QWidget *control, const QColor& color);

//取消特效颜色边框

void unSetFrame(QWidget* control);

private:

QWidget* widget;

QWidget* currentContrl; //记录当前焦点所在按钮

QList<ControlList> table;//按钮表格

const char* rowid;

const char* colid;

};

#endif // CONTROLTABLE_H

controltable.cpp

#include "controltable.h"

ControlTable::ControlTable(QWidget *parent):

QObject(parent),rowid("table_row"),colid("table_col")

{

Q_ASSERT(parent);

currentContrl = 0;

widget = parent;

}

/*

按钮表格图解,在阅读代码时,可参考此图解

btn代表按钮 null代表空

-----------------------

col1 col2 col3

row1 btn btn null

row2 null btn null

row3 btn btn btn

-----------------------

SwitchButtonWidget中的成员变量“table”是所有按钮指针和空指针的集合

例如table的第一行列表元素为[btn,btn,null]

在ui界面中,每个按钮的名称都采用 btn_行索引_列索引 的格式命名

这样取名只是为了直接能用ui指定行列

如果不想按照此命名规则排列,可在MyButton中添加行列成员,可达到相同效果

*/

void ControlTable::setTable(const QList<ControlList> &t)

{

bool isSetDefaultControl = false;

table = t;

for (int i = 0; i < rowCount(); ++i)

{

ControlList controList =table.at(i);

for (int j = 0; j < controList.size(); ++j)

{

if (table[i][j])

{

table[i][j]->setProperty(rowid, i);

table[i][j]->setProperty(colid, j);

if (!isSetDefaultControl)

{

selectControl(table[i][j]);

isSetDefaultControl = true;

}

}

}

}

}

void ControlTable::toUp()

{

QWidget* control = currentContrl;

int curRow = row(control);

int curCol = col(control);

if (isValid(curRow, curCol))

{

control = preControl(colControls(curCol), curRow);

selectControl(control);

}

}

void ControlTable::toDown()

{

QWidget* control = currentContrl;

int curRow = row(control);

int curCol = col(control);

if (isValid(curRow, curCol))

{

control = nextControl(colControls(curCol), curRow);

selectControl(control);

}

}

void ControlTable::toLeft()

{

QWidget* control = currentContrl;

int curRow = row(control);

int curCol = col(control);

if (isValid(curRow, curCol))

{

control = preControl(rowControls(curRow), curCol);

selectControl(control);

}

}

void ControlTable::toRight()

{

QWidget* control = currentContrl;

int curRow = row(control);

int curCol = col(control);

if (isValid(curRow, curCol))

{

control = nextControl(rowControls(curRow), curCol);

selectControl(control);

}

}

ControlList ControlTable::rowControls(int r)

{

return table[r];

}

ControlList ControlTable::colControls(int c)

{

ControlList ret;

for (int i = 0; i < rowCount(); ++i)

{

ret.append(table[i][c]);

}

return ret;

}

int ControlTable::row(QWidget *control)

{

if (!control)

{

return -1;

}

if (!control->property(rowid).isValid())

{

return -1;

}

return control->property(rowid).toInt();

}

int ControlTable::col(QWidget *control)

{

if (!control)

{

return -1;

}

if (!control->property(colid).isValid())

{

return -1;

}

return control->property(colid).toInt();

}

bool ControlTable::isValid(int r, int c)

{

return r != -1 && c != -1;

}

int ControlTable::rowCount()

{

return table.size();

}

void ControlTable::selectControl(QWidget *control)

{

QWidget* old= currentContrl;

if (old)

{

unSetFrame(old);

}

setFrame(control, Qt::red);

currentContrl = control;

emit controlSwitched(old, control);

}

QWidget *ControlTable::nextControl(const ControlList &controlList, int index)

{

QWidget * ret = 0;

int tmp = 0;

int size = controlList.size();

for (int i = index+1; i <= size+index; ++i)

{

tmp = i % size;

if (controlList.at(tmp) != 0)

{

ret = controlList.at(tmp);

break;

}

}

return ret;

}

QWidget *ControlTable::preControl(const ControlList &controlList, int index)

{

QWidget* ret = 0;

int tmp = 0;

int size = controlList.size();

for (int i = index-1; i >= index-size; --i)

{

if (i < 0)

{

tmp = i + size;

}

else

{

tmp = i;

}

if (controlList.at(tmp) != 0)

{

ret = controlList.at(tmp);

break;

}

}

return ret;

}

void ControlTable::setFrame(QWidget* control, const QColor &color)

{

QGraphicsDropShadowEffect* effect = new QGraphicsDropShadowEffect ();

effect->setBlurRadius(50); //设置模糊半径为50px

effect->setColor(color); //设置阴影颜色

effect->setOffset(0); //设置水平和垂直方向的偏移量都为0

control->setGraphicsEffect(effect); //为控件应用特效

}

void ControlTable::unSetFrame(QWidget* control)

{

control->setGraphicsEffect(0);

}

为了让按钮响应按键操作并统一管理显示特效框,我们自定义MyButton类,继承自QPushButton

mybutton.h

#ifndef MYBUTTON_H

#define MYBUTTON_H

#include <QPushButton>

class MyButton : public QPushButton

{

Q_OBJECT

public:

MyButton(QWidget* parent = 0);

protected:

void keyPressEvent(QKeyEvent* e);

};

#endif // MYBUTTON_H

mybutton.cpp

#include <QKeyEvent>

#include "mybutton.h"

MyButton::MyButton(QWidget *parent):

QPushButton(parent)

{

}

void MyButton::keyPressEvent(QKeyEvent *e)

{

int k = e->key();

if ( k == Qt::Key_Up

|| k == Qt::Key_Down

|| k == Qt::Key_Left

|| k == Qt::Key_Right)

{

e->ignore();//让这些事件继续上传给父窗口,在本例中指SwitchButtonWidget

}

else

{

e->accept();//停止其它事件向上传播

}

}

OK,到此,所有的代码全部编写完毕,运行程序,不出意外的话将会得到文章开头gif图片的按钮特效程序,使用方向键控制焦点框移动,是不是很酷啊。

 97fd02529225e4a53b298244fe8776ca.gif

好了,关于窗口特效的分享就到这里啦,其它特效使用方法和阴影特效非常类似,小豆君就不在这里一一列举了,最后,喜欢的朋友不要忘记点赞哦,您的支持就是对我最大的鼓励^_^

最近帮着几个小伙伴修改他们的项目代码时发现,他们对C++的语法和特性只是知其然而不知其所以然,所以这里给大家推荐一本可以解决这类问题的经典书《C++编程思想》,我想它的大名就不用我多介绍了,虽然这本书比较老了,但是经典就是经典,想要提高的朋友可以点击下面链接购买

欢迎关注微信公众号-小豆君Qt分享

301738b4025a3fbed4a30eb59f29ee9e.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/137522
推荐阅读
  

闽ICP备14008679号