• 21196阅读
  • 25回复

教你如何用Qt做透明的窗体,setMask,Qt,Opacity, [复制链接]

上一主题 下一主题
离线318065268
 
只看楼主 倒序阅读 楼主  发表于: 2010-09-10
— 本帖被 XChinux 设置为精华(2011-07-06) —
// In this function, we can get the height and width of the current widget
void Widget::resizeEvent(QResizeEvent *)
{
    // Use a bitmap as a mask. A bitmap only has two kind of colors: white(value is 0)
    // or black(other values). When we use it to set mask, we can see the window at the position
    // where the color value is 0, and other place will be transparent.
    QBitmap bitMap(width(),height()); // A bit map has the same size with current widget
    QPainter painter(&bitMap);
    painter.setPen(QColor(255,255,255)); // Any color that is not QRgb(0,0,0) is right
    painter.drawRect(0,0,width(),height());

    // Now begin to draw the place where we want to show it
    painter.setPen(QColor(0,0,0));
    drawTextOnWin(&painter);
    drawImageOnWin(&painter);

    setMask(bitMap);
}
void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(QColor(Qt::red));
    // As the place where we want to draw has been set opaque in the resizeEvent, so what we draw here
    // will be shown
    drawTextOnWin(&painter);
    drawImageOnWin(&painter);
}
void Widget::drawTextOnWin(QPainter *painter)
{
    painter->setFont(QFont(font().family(),15));
    painter->drawText( (width()-300)/2,0,300,50,Qt::AlignHCenter,"Now you can see me!");
}
void Widget::drawImageOnWin(QPainter *painter)
{
    QPixmap imageTest(":/imageItem/pngImage.png");
    painter->drawPixmap( (width()-imageTest.width())/2, (height()-imageTest.height())/2,
                          imageTest.width(), imageTest.height(), imageTest );
}

上面是源码。附件里是效果图。
Qt提供了setOpacity的函数,但是使用之后,窗体所有子控件都变成同样的透明色了。
这里我们利用setMask()函数,以QBitmap为参数,通过对QBitmap做精细的操作(关键在于QBitmap支持用painter直接在上面绘制),最终达到这样的效果:我们想要透明的地方变成透明,我们想要放置部件的地方变成非透明可见的。这样就达到了我们想要的效果。
具体实现的方法也很简单:如果你想在paintEvent里面绘制任何内容,也要同时在QBitmap上做绘制,前提是在QBitmap上绘制的时候画笔的rgb设置成QRgb(0,0,0)。
道理我已经讲明白了。大家可以自己把代码弄到自己的类里面实验一下。
例子中只是最简单的演示,按照这个思路我想可以做出更多更灵活的应用的,比如可以让窗体介于透明和非透明之间(这里需要准备一个对应的透明色的png图片,或者使用相应的Qt函数来做都行)。最关键的是这种方法下透明度的操作不会影响到子控件的。
这里的
Email  rsail@126.com(私人邮箱)
QQ:   318065268
离线beaujolais
只看该作者 1楼 发表于: 2010-09-10
windows 上用setOpacity(0.8) 更 简单。

x11就只能这样做了~~
离线318065268
只看该作者 2楼 发表于: 2010-09-10
回 1楼(beaujolais) 的帖子
你都没有搞清楚我这是要干嘛。
帖子里说的很清楚“Qt提供了setOpacity的函数,但是使用之后,窗体所有子控件都变成同样的透明色了。”
Email  rsail@126.com(私人邮箱)
QQ:   318065268
离线iroot
只看该作者 3楼 发表于: 2010-09-11
网上那些 所谓透明方法,在KDE下失效,黑漆漆的背景。 那些方法 需要KDE开了特效后,才能实现透明。真是怄火。

现在 我来试试 楼主这个方法,看看, 在没有开桌面特效的KDE下,能否实现这样的透明?~
[ 此帖被iroot在2010-09-11 17:17重新编辑 ]
离线iroot
只看该作者 4楼 发表于: 2010-09-11
试过了,有重叠现象。
如图:(没有加入 绘制图片 的函数)

KUbuntu 下:




Window 7 下:





  
离线318065268
只看该作者 5楼 发表于: 2010-09-12
回 4楼(iroot) 的帖子
我这没有win7,不过windows下试过,没有那种重叠的现象。出现重叠的现象,一种可能是代码里面有些地方写的不对。因为不会无缘无故的出现黄颜色的内容,应该是你自己在代码里面添加了一些别的内容。
Email  rsail@126.com(私人邮箱)
QQ:   318065268
离线0354030w

只看该作者 6楼 发表于: 2010-09-15
在XP上试了一下,好像也是有重叠。请问楼主不知道该如何解决?


离线davis45
只看该作者 7楼 发表于: 2010-09-16
这个帖子一定要顶,等我有空了一定试一试,看起来很炫啊
谢谢大家的指教
离线iroot
只看该作者 8楼 发表于: 2010-09-16
回 5楼(318065268) 的帖子
没有添加任何额外代码,只是 把 绘图代码去掉而已。
离线yyxl
只看该作者 9楼 发表于: 2010-09-23
不错啊!学习了
离线yyxl
只看该作者 10楼 发表于: 2010-11-09
Spyder
离线mefalo
只看该作者 11楼 发表于: 2010-11-09
不过老感觉这个透明的锯齿很严重有什么好的解决办法吗?
离线wzsiatf
只看该作者 12楼 发表于: 2010-11-11
我也试了,在Windows7下,也有一部分图像缺失
离线luoyes

只看该作者 13楼 发表于: 2010-11-12
思路很好,标记一下
离线uihjk999
只看该作者 14楼 发表于: 2011-01-04
感谢分享!Qt纯菜鸟路过,标记之
离线zhutousame
只看该作者 15楼 发表于: 2011-03-20
额........我的qpushButton,label和标题栏都不见了....哪里做错了吗?还是说本来就没有的?
离线jiusuihe
只看该作者 16楼 发表于: 2011-03-23
嗯,不错,顶下。
离线longteng9
只看该作者 17楼 发表于: 2011-04-09
我是绘制的图像然后setmask的,和楼主效果类似,也是透明的
离线vboylin
只看该作者 18楼 发表于: 2011-04-09
可能是绘图前没把定义的图先清空 以前我有过这样的事情 debug下调的好好的图 已变成release就花了 后然发现是release是定义了图就得先清空 要不然里面的数据随机的就花了 不知道重印是不是也是这个原因
离线gi13
只看该作者 19楼 发表于: 2011-04-11
好好研习一下
离线hats

只看该作者 20楼 发表于: 2011-11-06
这个很实用
VC2005 + Qt 4.7.0
VC6 + Qt 4.5.0
WIndows XP
Mac OS X 10.6.8
CentOS6.2
离线gerryleeke

只看该作者 21楼 发表于: 2012-04-27
mark一下,改天用用
离线zooood
只看该作者 22楼 发表于: 2012-04-27
mark之
离线hyh0lh

只看该作者 23楼 发表于: 2013-07-17
先谢谢楼主,我现在正为同一个问题头疼。前期工作没有考虑到这个内容,导致现在要把整个界面进行透明话处理。头疼啊~
离线hyh0lh

只看该作者 24楼 发表于: 2013-07-18
如何在透空窗体上如何绘制一个复杂的控件,或者说窗体。有没有成熟的经验
只看该作者 25楼 发表于: 2013-09-15
mark一下
快速回复
限100 字节
 
上一个 下一个