Qt 不规则窗体的实现(构造函数里setPaletteBackgroundPixmap后设置setMask)
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 的手工代码实现:
#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)的更多相关文章
- Qt 不规则窗体 – 鼠标点击穿透(Linux也可以,有对x11的配置的方法)
之前写过如何用 Qt 现成的方法写出无边框半透明的不规则窗体:<Qt 不规则窗体 – 无边框半透明> 其实有一个很特殊的窗体属性一直以来都伴随着不规则窗体出现,这就是本文要介绍的鼠标点击穿 ...
- QT实现不规则窗体
看到网上有很多不规则窗体的实现,效果很酷.于是使用QT也实现了一个,QT的不规则窗体实现非常简单,只需要设置一个mask(遮掩)图片,这个图片的格式可以使用png或bmp格式,我使用了png格式,默认 ...
- paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制
源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...
- 【翻译】利用Qt设计师窗体在运行时创建用户界面(Creating a user interface from a Qt Designer form at run-time)
利用Qt设计师窗体在运行时创建用户界面 我们利用Calculator窗体例子中创建的窗体(Form)来展示当一个应用(application)已经生成后,是可以在其运行时产生与例子中相同的用户界面. ...
- Qt创建窗体的过程
版权声明 本文为原创作品,请尊重作者的劳动成果.转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18”和 主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口 ...
- WPF界面设计技巧(1)—不规则窗体图文指南
原文:WPF界面设计技巧(1)-不规则窗体图文指南 初到园子,奉上第一篇入门级教程,请勿见笑. 以往WinForm编程中,实现不规则窗体是有一定难度的,更难的是不规则窗体的边缘抗锯齿及局部透明处理.而 ...
- QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)
前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...
- WPF中不规则窗体与WindowsFormsHost控件的兼容问题完美解决方案
首先先得瑟一下,有关WPF中不规则窗体与WindowsFormsHost控件不兼容的问题,网上给出的解决方案不能满足所有的情况,是有特定条件的,比如 WPF中不规则窗体与WebBrowser控件的兼 ...
- WPF中不规则窗体与WebBrowser控件的兼容问题解决办法
原文:WPF中不规则窗体与WebBrowser控件的兼容问题解决办法 引言 这几天受委托开发一个网络电视项目,要求初步先使用内嵌网页形式实现视频播放和选单,以后再考虑将网页中的所有功能整合进桌面程序. ...
随机推荐
- poj2891--扩展欧几里德算法
/* 该题使用的是扩展欧几里德算法,求模线性同余方程: 分析题目:以题目输出结果为例 ,要求得到一个整数X可以满足 X % a = r,a,r,为数组名: 设数组元素为两个时, 列出方程:X % a1 ...
- SEL数据类型,@selector的用法,以及调用SEL
1.SEL数据类型 SEL是个指针类型的数据,类似C语言中的函数指针.在OC中,每个对象方法都有其对应着一个SEL变量.当我们调用对象方法时,编译器会将该方法转换成一个SEL的数据,然后去类中寻找该方 ...
- 状态压缩DP------学习小记
状态DP主要用的还是DP思想,顾名思义,加了一个状态,主要是用来求状态个数的. 状态是用二进制数来表示的,也就是用0或1来表示,每一行有一个状态数,就是由这一行的0或1组成的,首先我们要获得每行的状态 ...
- Ubuntu12.04 配置Java开发环境:JDK1.7+Eclipse+Tomcat7.0
软硬件环境 Ubuntu12.04+JDK1.7+Eclipse+Tomcat7.0 内容列表 1.安装JDK1.7,配置JAVA环境 2.安装Eclipse 3.安装Tomcat7.0 1.安装JD ...
- Python封装的访问MySQL数据库的类及DEMO
# Filename:mysql_class.py # Author:Rain.Zen; Date: 2014-04-15 import MySQLdb class MyDb: '''初始化[类似于构 ...
- php页面相互调用的知识点
目前我们有这样一个需求: (1) a.php 页面要使用 b.php 定义的函数,我们可以使用 如下指令 require require_once include include_once 举 ...
- Oracle EBS-SQL (SYS-17):查询一张报表在哪个职责下面.sql
1.查询该报表的 concurrent_program_id SQL如下: SELECT t.application_id, t.concurrent_program_id, t.* FROM FND ...
- javascript将异步校验表单改写为同步表单
同步表单校验的缺点 响应错误信息时,需要重新加载整个页面(虽然有缓存,客户端仍然需要通过http协议对比每个文件是否有更新,以保持文件最新) 服务器响应错误以后,用户之前所输入的信息全部丢失了,用户需 ...
- dllimport与dllexport作用与区别
我相信写WIN32程序的人,做过DLL,都会很清楚__declspec(dllexport)的作用,它就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法.当然,如果你的DLL里全是C++的类的话 ...
- Dreamweaver中打开CodeSmith文件
电脑环境:Windows2008+Dreamweaver 8英文版本 问题描述:Dreamweaver中默认打开文档时不支持打开CodeSmith模板文件对应的.cst后缀名文件,截图如下: 解决步骤 ...