Qt—特殊效果窗体

x33g5p2x  于2022-04-02 转载在 其他  
字(4.3k)|赞(0)|评价(0)|浏览(323)

特殊窗体

不规则窗体

使用样式表可以实现矩形、圆形等规则形状的部件,不过,有时想设计一个不规则形状的部件或者窗口,使得应用程序的外观更加个性化。Qt中提供了部件遮罩( mask)来实现不规则窗体。

新建Qt Widgets应用,项目名称为mymask,基类选择QWidget,类名保持Widget不变。完成后向项目目录中放一张背景透明的PNG图片(笔者这里是yafeilinux.png),然后再向项目中添加一个Qt资源文件,建立好后先添加前缀“/image”,然后再将图片添加进来并保存更改。然后到设计模式,向界面上拖入一个Label,设置其宽度为56,高度为67。下面到 widget. cpp文件中,先添加头文件包含:

#include <QPixmap>
#include <QBitmap>
#include <QPainter>

再到构造函数中添加如下代码:

QPixmap pixmap(":/image/yafeilinux.png");
        ui->label->setPixmap(pixmap);
        ui->label->setMask(pixmap.mask());

这里使用QPixmap类加载了资源文件中的图片,使用setPixmap()为标签设置了图片,最后调用QLabel的 setMask()函数为标签设置了遮罩。这时运行程序可以看到,标签部件显示成了图片的形状。

下面来看下怎样为整个窗口设置遮罩。进入 widget.h文件,声明两个事件处理函数:

protected:
    void paintEvent(QPaintEvent *);
    void mousePressEvent(QMouseEvent *);

然后再到widget.cpp文件中,注释掉前面lebel-setPixmap的构造函数的代码,并添加如下:

QPixmap pix;
    // 加载图片
    pix.load(":/image/yafeilinux.png");
    // 设置窗口大小为图片大小
    resize(pix.size());
    // 为窗口设置遮罩
    setMask(pix.mask());

这里调用setMask来设置遮罩。下面添加二个事件处理函数的定义:

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    // 从窗口左上角开始绘制图片
    painter.drawPixmap(0, 0, QPixmap(":/image/yafeilinux.png"));
}

void Widget::mousePressEvent(QMouseEvent *)
{   // 关闭窗口
    close();
}

必须在paintEvent()函数中将图片绘制在窗口上,这样运行程序时才可以正常显示图片.

鼠标按下事件中只是进行了简单的关闭窗口操作

窗口变为图片的形状

这个程序中使用了一张图片来为部件或者窗口设置遮罩,其实还可以使用QRegion设置一个区域来作为遮罩,这个就不再讲解了,有兴趣的读者可以参考QWidget的setMask( const QRegion &region)函数。

透明窗体

只需要设置背景色指定alpha即可

QPushButton{background-color:rgba(255,255,255,100)}

其中,rgba()中的a就是指alpha, 它的取值为0~255,取值为0时完全透明,取值为255时完全不透明。

这里a的值为100,这样会出现半透明的效果,因为前面的r
(红)、g(绿)、b(蓝)的值均为255,所以是白色,最终的效果是按钮的背景为半透明的白色。

部件的透明效果可以使用这种方式来设置,但是,作为顶级部件的窗口却无法使用这种方式来实现透明效果

不过,可以使用其他两种方法来实现透明效果。
新建Qt Widgets 应用,项目名称为mytranslucent,基类选择QWidget,类名保持Widget 不变。

建好项目后,在设计模式向界面上拖入一个Label、一个Push Button和一个Progress Bar,

然后在widget.cpp文件中的构造函数里添加一行代码:

//    // 设置窗口的不透明度为0.5
    setWindowOpacity(0.5);

使用setWindowOpacity()函数就可以实现窗口的透明效果,它的参数取值范围为0.0~1.0,取值为0.0时完全透明,取值为1.0时完全不透明。

这时运行程序,效果如图所示。

可以看到,这样实现的效果是整个应用程序界面都是半透明的,如果不想让窗口中的部件透明,那该怎么实现呢?下面来看另一种方法。

先将构造丽数中的setWindowOpacity()函数调用注释掉,然后再添加下面两行代码:

setWindowFlags(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);

这里使用了setAttribute()函数指定窗口的Qt:: WA_TranslucentBackground属性,它可以使窗体背景透明,而其中的部件不受影响。不过在Windows下,还要使用setWindowFlags()函数指定Qt::FramelessWindowHint标志,这样才能实现透明效果。

这时运行程序会发现,窗口没有了标题栏,这时要想关闭窗口,就要使用Qt Creator应用程序输出栏上的红色按钮来强行关闭程序。这样实现的效果是背景完全透明的。

要是还想实现半透明效果,可以使用重绘事件。
先在widget. h文件中声明paintEvent()函数:

protected:
void paintEvent(QPaintEvent *);

然后到widget.cpp文件中添加头文件#include< QPainter>,再添加paintEvent()函数

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.fillRect(rect(), QColor(255,255,255,100));
}

这里先使用rect()函数获取窗口的内部矩形,它不包含任何边框。然后使用半透明的白色对这个矩形进行填充,可以运行程序查看运行效果。

fillRect()函数可以指定任意的一个区域,所以可以实现窗体的部分区域全部透明,部分区域半透明或者不透明的效果。

使用第一种方法会使整个应用程序都成为半透明效果;第二种方法可以实现只是顶层窗口的背景透明,不过,它没有了标题栏和边框,还需要手动为其添加一个标题栏。另外,使用第11章讲到的图形效果也可以实现部件的透明效果,而且使用它还可以实现模糊、阴影和染色等特殊效果。

下面接着在widget.cpp文件中添加头文件包含#include< QGraphicsDropShadowEffect>,然后在构造函数中添加如下代码;

// 创建阴影效果
    QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
    // 设置阴影颜色
    effect->setColor(QColor(100, 100, 100, 100));
    // 设置阴影模糊半径
    effect->setBlurRadius(2);
    // 设置阴影偏移值
    effect->setOffset(10);
    // 标签部件使用阴影效果
    ui->label->setGraphicsEffect(effect);

为标签部件设置了阴影效果,如果要设置透明效果,可以创建QGraphicsOpacityEffect对象,然后使用setOpacity()设置透明度即可

实现window7毛玻璃效果

下面就来看一下如何实现毛玻璃窗口效果。本小节内容可以在帮助中通过Qt Windows Extras Overview关键字查看。

新建Qt Widgets应用,项目名称为mydwm,类名为MainWindow,基类为QMain Window保持不变。建好项目后,在设计模式向界面上拖人一个Label并修改显示文本为“毛玻璃窗口效果”,然后在mydwm.pro中添加一行代码:

QT += winextras

下面打开widget.cpp文件,添加头文件#include< QtWinExtras>,再到构造函数里添加代码:

if (QtWin::isCompositionEnabled()) {
        QtWin::extendFrameIntoClientArea(this, -1, -1, -1, -1);
        setAttribute(Qt::WA_TranslucentBackground, true);
        setAttribute(Qt::WA_NoSystemBackground, false);
        setStyleSheet("MainWindow { background: transparent; }");
    } else {
        QtWin::resetExtendedFrame(this);
        setAttribute(Qt::WA_TranslucentBackground, false);
        setStyleSheet(QString("MainWindow { background: %1; }")
                      .arg(QtWin::realColorizationColor().name()));
    }

这里首先使用isCompositionEnabled ()判断DWM(Desktop Window Manager,Windows桌面窗口管理器)合成是否可用,当其可用时才可以实现毛玻璃框架效果。

extendFrameIntoClientArea()可以扩展毛玻璃边框效果到客户区域,第一个参数是要设置的窗口;后面4个参数是左、上、右、下边距,就是要从窗口的边界开始向内多大区域使用玻璃边框效果,设置为-1表示所有区域都使用毛玻璃效果。另外,还要使用setAttribute()设置窗口属性。最后使用setStyleSheet()设置窗口的背景透明,这里一定要注意,样式表中的选择器要设置为窗口的类名

现在运行程序,效果如图所示。

Qt Windows Extras模块中的其他特色功能这里就不再讲述了,可以参考MusicPlayer示例程序,也可以参考《Qt及 Qt Quick开发实战精解(第2版)》中音乐播放器实例的相关内容。

总结

总结:还是需要CSS的应用

相关文章