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 <qapplication.h>
#include <qwidget.h>
#include <qpixmap.h>
#include <qbitmap.h>
#include <qpoint.h>

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的手工代码实现,注意差别:
#include <QApplication>
#include <QWidget>
#include <QPixmap>
#include <QBitmap>
#include <QPoint>
#include <QPalette>
#include <QMouseEvent>

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();

}

http://www.cnblogs.com/SkylineSoft/articles/2046299.html

Qt 不规则窗体的实现(构造函数里setPaletteBackgroundPixmap后设置setMask)的更多相关文章

  1. Qt 不规则窗体 – 鼠标点击穿透(Linux也可以,有对x11的配置的方法)

    之前写过如何用 Qt 现成的方法写出无边框半透明的不规则窗体:<Qt 不规则窗体 – 无边框半透明> 其实有一个很特殊的窗体属性一直以来都伴随着不规则窗体出现,这就是本文要介绍的鼠标点击穿 ...

  2. QT实现不规则窗体

    看到网上有很多不规则窗体的实现,效果很酷.于是使用QT也实现了一个,QT的不规则窗体实现非常简单,只需要设置一个mask(遮掩)图片,这个图片的格式可以使用png或bmp格式,我使用了png格式,默认 ...

  3. paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制

    源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...

  4. 【翻译】利用Qt设计师窗体在运行时创建用户界面(Creating a user interface from a Qt Designer form at run-time)

    利用Qt设计师窗体在运行时创建用户界面 我们利用Calculator窗体例子中创建的窗体(Form)来展示当一个应用(application)已经生成后,是可以在其运行时产生与例子中相同的用户界面. ...

  5. Qt创建窗体的过程

    版权声明 本文为原创作品,请尊重作者的劳动成果.转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18”和 主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口 ...

  6. WPF界面设计技巧(1)—不规则窗体图文指南

    原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...

  7. QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)

    前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...

  8. WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案

    首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如  WPF中不规则窗体与WebBrowser控件的兼 ...

  9. WPF中不规则窗体与WebBrowser控件的兼容问题解决办法

    原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...

随机推荐

  1. linux创建用户和组

    linux下创建用户(一) Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号一方面可以帮助系 ...

  2. 查看mysql字符集及修改表结构

    MySQL 乱码的根源是的 MySQL 字符集设置不当的问题,本文汇总了有关查看 MySQL 字符集的命令.包括查看 MySQL 数据库服务器字符集.查看 MySQL 数据库字符集,以及数据表和字段的 ...

  3. 什么是Web前端,Web前端是做什么的?

    什么是Web前端 Web前端,顾名思义是来做Web的前端的.而Web前端开发应该就是来开发基于Web前端的相关应用的或者说是来开发前端的.那么,前端又是什么呢?我们这里所说的前端泛指Web前端,也就是 ...

  4. 使用mysql_query()方法操纵数据库以及综合实例

    1.利用insert 语句添加记录 <? require('conn.php'); mysql_query( "insert into lyb ( title, content, au ...

  5. GO语言搭建

    最近对GO语言产生了浓厚的兴趣.因为GO语言不仅仅可以开发桌面.web程序,最吸引我的是安卓大有往GO语言全方位靠拢的趋势,自家的系统还是用自家的语言开发比较靠谱. 用一句话来说:Go语言是谷歌200 ...

  6. 一个由proguard与fastJson引起的血案

    更多内容在这里查看 https://ahangchen.gitbooks.io/windy-afternoon/content/ 更新微信sdk导致ComposeData中的内部类ComposeDat ...

  7. Windows Azure Web Role 的 IIS 重置

     如果您是一名 Web开发人员,您很可能使用过"简单快捷"的iisreset命令重置运行不正常的 IIS主机.这种方法通常在经典的 Windows Server VM上非常有效 ...

  8. poj1617---columnar encryption

    题意:给出keyword,如BATBOY,A的ascii值最小,所以第二列最先输出,B有两个,左边的先输出,也就是说,接下来输出第一列和第4列, 所以每一个字母都带有一个ascii值和一个序号,用结构 ...

  9. Gdal 1.11.0 添加 Postgresql 9.1 sqlite3 支持

    OS环境Ubuntu12.04 32bit 因为公司一个功能要用到gdal 的ogr2ogr命令转换shp数据,需要能往postgis和sqlite 中插入数据. 用gdal1.11.0的源码默认安装 ...

  10. [虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(八)

    目的: 1. 通过网页读取watchdog的信息 2. 通过网页设置watchdog 准备工作: 1. 选择一个web框架,选用 cherrypy $ sudo apt-get install pyt ...