LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 4702|回复: 6

使用SWT开发界面,如何作出透明背景的控件、窗口呢?

[复制链接]
发表于 2005-11-29 15:52:36 | 显示全部楼层 |阅读模式
使用SWT开发用户界面,如何作出透明背景的控件、窗口呢?

如附件显示的样子。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2005-11-29 19:59:20 | 显示全部楼层
自绘界面,绘制时调整alpha值,alpha越小,透明度越高
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-30 15:17:22 | 显示全部楼层
Post by luma
自绘界面,绘制时调整alpha值,alpha越小,透明度越高


用下面的代码在Canvas上面绘制。有问题,如附件图,第一幅是程序刚刚启动运行的时候,一切正常,然而在调整窗口大小之后,图像就如图二了,乱了,只能最小化然后恢复才能使窗口绘制正常。求助,如何做能解决这个问题?

还有一点奇怪的,我只能使用canvas绘制,如果将绘制直接放在shell也就是窗口上,就完全没有效果。怀疑窗口重新绘制事件首先把窗口背景颜色画上去了,才调用paintlistener。可是为什么放在canvas上就可以?疑惑,大大的疑惑。难道用canvas覆盖主窗口后(用的fill layout摆放的canvas),主窗口就完全不重绘了?

另外,目前用alpha控制透明的代码和我最终想要达到的还有一点差距,顶楼附件现实的那个效果更好一点:当透明窗口所覆盖下面的窗口内容发生变化时(比如电影播放窗口),也能反映出来。可是覆盖的窗口发生变化时,目前窗口不会接到绘制事件,也就不能反映后面窗口的变化。所以,效果还缺一点点。

我的代码如下:


  1. import org.eclipse.swt.*;
  2. import org.eclipse.swt.graphics.*;
  3. import org.eclipse.swt.layout.FillLayout;
  4. import org.eclipse.swt.widgets.*;
  5. import org.eclipse.swt.events.*;

  6. public class Talpha {

  7.         /**
  8.          * @param args
  9.          */
  10.         public static void main(String[] args) {
  11.                 // TODO Auto-generated method stub
  12.                 final Display display = new Display();
  13.                 final Shell shell = new Shell(display);

  14.                 Canvas canvas = new Canvas(shell, SWT.NO_BACKGROUND);
  15. //使用paintlistener,保证每次均重新绘制。
  16.                 canvas.addPaintListener(new PaintListener() {
  17.                         public void paintControl(PaintEvent e) {
  18.                                 GC gc = e.gc;
  19. //读图像
  20.                         ImageData imageData = new ImageData("imgs/pt.jpg");
  21. //这里是建立从左到右的渐进Alpha。
  22.                                 byte[] alphaValues = new byte[imageData.height * imageData.width];
  23.                                 for (int j = 0; j < imageData.height; j++) {
  24.                                         for (int i = 0; i < imageData.width; i++) {
  25.                                                 alphaValues[j * imageData.width + i] = (byte) (255 - 255
  26.                                                                 * i / imageData.width);
  27.                                         }
  28.                                 }
  29.                                 imageData.alphaData = alphaValues;
  30.                                 Image image = new Image(display, imageData);
  31. //绘制                               
  32.                         gc.drawImage(image,0,0);
  33.                         }
  34.                 });

  35.                 FillLayout fillLayout = new FillLayout();
  36.                 fillLayout.type = SWT.VERTICAL;
  37.                 shell.setLayout(fillLayout);
  38.                 shell.setSize(200, 600);
  39.                 shell.open();
  40.                 while (!shell.isDisposed()) {
  41.                         if (!display.readAndDispatch())
  42.                                 display.sleep();
  43.                 }
  44.                 display.dispose();
  45.         }

  46. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-11-30 16:57:36 | 显示全部楼层
另外,多个widgets互相覆盖测试,不成功。widgets互相覆盖的区域,仅能表现最上面的widget绘图。被覆盖的则完全覆盖。当然,从整个窗口来看上仍然保持了被覆盖的窗口绘图。

如图,背后的eclipse编程界面能看到,但本窗口内部被覆盖控件却不能看到。可以看出,实际上swt的alpha处理过程大致是:读取整个界面上被当前窗口覆盖部分的图像,drawImage时做alpha处理,但对于本窗口控件间的互相覆盖关系并不能aware。控件绘制时,尽管控件之间覆盖时有先后顺序,然而swt都是简单取背后被覆盖窗口的图像做alpha,导致控件之间不能透明。

奇怪阿,怎么办呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2005-12-1 11:56:24 | 显示全部楼层
swt现在做不到真正的透明,只能是模拟,效果自然有折扣

而且你也不应该在canvas上面画,应该直接在shell上面画

然后监听shell的移动事件,以便在移动的时候重画

同时再启动一个定时任务,每隔一段时间重画,近似的实现"反映覆盖窗口变化"
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-12-1 13:35:46 | 显示全部楼层
Post by luma
swt现在做不到真正的透明,只能是模拟,效果自然有折扣

而且你也不应该在canvas上面画,应该直接在shell上面画

然后监听shell的移动事件,以便在移动的时候重画

同时再启动一个定时任务,每隔一段时间重画,近似的实现"反映覆盖窗口变化"



谢谢回复   :thank 。不过我做过实验给shell增加 paintlistener,直接在shell上绘制,结果不成功。怀疑窗口重新绘制事件首先把窗口背景颜色画上去了,才调用paintlistener, 然后绘制的图片半透明看到窗口背景颜色。可是如果把paintlistener放在任意canvas上就可以。很是疑惑。 :ask  :ask
回复 支持 反对

使用道具 举报

发表于 2005-12-3 09:33:57 | 显示全部楼层
自己慢慢琢磨吧,可以参考edu.tsinghua.lumaqq.widgets.qstyle.DieAway
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表