Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1697306
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类:

2011-01-21 13:21:26


准备两个图,一个是要显示在窗体的图片,一个是蒙板,蒙板的黑色部分是要保留的,白色是要去掉的。 

我准备了2张图,要显示的图片是"tmp.png",蒙板是"mask.png".如图

下面的程序都有个毛病,不能拖出幕窗口以外,为什么呢?

请注意一个是窗口和MASK图片的大小问题,还有就是只有无拖动栏的窗体MASK成不规则窗体才允许拖出屏幕窗口以外。

GTK程序参考 gtk_widget_shape_combine_mask

 tmp.png (2.41 KB)
 

 

使用 Qt 制作 Skin: http://www-128.ibm.com/developer ... /qt/skin/index.html

Skin(表皮) 是制作比较酷的软件界面的有利工具. 一个软件可以同时使用多种Skin 以取得不同的外观, 使同一个软件有截然不同的风格. 用户可以根据自己的喜好选择 不同的风格. 本节介绍使用 Qt 制作 Skin 的方法.

软件界面的风格变化可以通过两种机制完成,一种是通过设置主题(Themes),它使用 界面库本身所具有的对界面组件(Components)的控制能力切换显示风格;另外一种是 通过提供不同系列的图片来切换显示界面,即这里所讲的 Skin。

制作表皮有几个重要的因素值得考虑:

1. 使用无边界的窗口
在 XWindow 下,无边界的窗口是指不受窗口管理器管理的边界不规则的窗口。由于不受窗口管理器管理管理,所以软件窗口界面没有附加的标题 条(Title Bar)等。 在Qt中,建立无边界窗口的最简单的方法 是设置 QWidget 的 WFlags 的值 是 WStyle_NoBorder。它定义在 qnamespace.h 中。不规则窗口的特点则要求对整个 窗口使用图像掩码。使用 X 窗口形状的 扩展(X Shape Extension)来达到要求。在 Qt 中可以直接使用,


QBitmap bm;
bm = *(Pixmaps[MASK]);
setMask(bm);
setBackgroundPixmap(*Pixmaps[BACKGROUND]);


2. 窗口的移动
由于上述窗口不受窗口管理器的管理的特性,所以移动窗口需要特殊处理,一般的 方法是截取根Widget的鼠标按钮事件,自己处理鼠标点击和移动的事件。


void SkinDemo::mouseMoveEvent(QMouseEvent *e)
{
QPoint newpos = e->globalPos();
QPoint upleft = pos0 + newpos - last;
move(upleft);
}

void SkinDemo::mousePressEvent(QMouseEvent *e)
{
last = e->globalPos();
pos0 = e->globalPos() - e->pos();
}


这里我们取得的鼠标位置是绝对位置,即相对于根窗口的位置,同时也记录下窗口 左上角的位置,当鼠标移动时,取得新的绝对位置,则窗口左上角 的新位置应该 是原来位置与鼠标移动的位置之差。

3. 按钮的制作
在 例子( qt-skin-example.tar.gz) 中,我们重新定义了鼠标按下和鼠标移动的事件处理 函数,并且含有按钮的所有信 息,主工作区的所有信息等。主工作区的信息是它的位置和尺寸,主窗口的信息是它所使用的背景图片和图片的掩码(用来制造不规则 窗口),所以整个主窗口的 大小可以由图片的尺寸来决定。几个按钮的信息包含它们的 位置,它们的大小由图片的大小来决定。
对于表皮中的图像按钮, 设置它的父类是 QButton,这种按钮由两幅图片构成,一幅图片是正常状态(Normal),一幅图片是按钮按下时 的状态(Activated)。有时也可以设置成四 种状态,即增加禁止状态(Disabled)和鼠标指针进入时的状态 (Hovered)。

Qt3 的手工代码实现:


CODE:#include 
#include 
#include 
#include 
#include 

class myclass:public QWidget
{
    public:
        myclass();
    protected:
        void mouseMoveEvent(QMouseEvent *e);
        void mousePressEvent(QMouseEvent *e);
    private:
        QPixmap *pixmap;
        QBitmap *bitmap;
        QPoint last,pos0;
};

myclass::myclass()
{
    setGeometry(0,0,120,120);
    pixmap=new QPixmap("/doc/test/a/tmp.png");
    bitmap=new QBitmap("/doc/test/a/mask.png");
    setPaletteBackgroundPixmap(*pixmap);
    setMask(*bitmap);
}
void myclass::mouseMoveEvent(QMouseEvent *e)
{
    if(e->state()==LeftButton)
    {
    QPoint newpos = e->globalPos();
    QPoint upleft = pos0 + newpos - last;
    move(upleft);
    }
}

void myclass::mousePressEvent(QMouseEvent *e)
{
    last = e->globalPos();
    pos0 = e->globalPos() - e->pos();
}
         

int main(int argc,char *argv[])
{
    QApplication a(argc,argv);
    myclass w;
    a.setMainWidget(&w);
    w.show();
    return a.exec();
}
 



Qt4的手工代码实现,注意差别:




CODE:#include 
#include 
#include 
#include 
#include 
#include 
#include 

class myclass:public QWidget
{
 public:
 myclass();
 protected:
 void mouseMoveEvent(QMouseEvent *e);
 void mousePressEvent(QMouseEvent *e);
 private:
 QPixmap *pixmap;
 QBitmap *bitmap;
 QPoint last,pos0;
};
myclass::myclass()
{
 setGeometry(0,0,120,120);
 pixmap=new QPixmap("/doc/test/a/tmp.png");
 bitmap=new QBitmap("/doc/test/a/mask.png");
 QPalette palette;
 palette.setBrush(backgroundRole(), QBrush(*pixmap));
 setPalette(palette);
 setMask(*bitmap);
}
void myclass::mouseMoveEvent(QMouseEvent *e)
{
 if (!(e->buttons() & Qt::LeftButton))
 return;
 QPoint newpos = e->globalPos();
 QPoint upleft = pos0 + newpos - last;
 move(upleft);
}
void myclass::mousePressEvent(QMouseEvent *e)

 if (e->button() == Qt::LeftButton)
 last = e->globalPos();
 pos0 = e->globalPos() - e->pos();
}

int main(int argc,char *argv[])
{
 QApplication a(argc,argv);
 myclass w;
 w.show();
 return a.exec();
}




















阅读(536) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~