android on qt 之模拟jquery-mobile控件的box-shadow效果
2015-07-14 09:51
786 查看
一.背景图片描述
1. 名称定义
在Qt的控件中,加入类似CSS3的box-shodow的阴影效果。由于QSS不支持box-shodow属性,故而通过截图拼凑来模拟。
图1. radius_border.png
上图为我们需要准备的背景图(radius_border.png):
矩形区域(x2,y2,x5,y5)所内切包含的圆角矩形背景透明,之所以透明,是为了不遮掩住QT的控件背景,比如QLineEdit;
矩形区域(x1,y1,x6,y6)所内切包含的蓝色带状区域为控件的阴影;
矩形区域(x1,y1,x3,y3)所内切包含的蓝色扇环区域命名为leftTop;
矩形区域(x3,y1,x4,y2)所内切包含的蓝色矩形区域命名为top;
矩形区域(x4,y1,x6,y3)所内切包含的蓝色扇环区域命名为rightTop;
矩形区域(x5,y3,x6,y4)所内切包含的蓝色矩形区域命名为right;
矩形区域(x4,y4,x6,y6)所内切包含的蓝色扇环区域命名为rightBottom;
矩形区域(x3y5,x4,y6)所内切包含的蓝色矩形区域命名为bottom;
矩形区域(x1,y4,x3,y6)所内切包含的蓝色扇环区域命名为leftBottom
矩形区域(x1,y3,x2,y4)所内切包含的蓝色矩形区域命名为left;
注:当border_radius为0时,阴影即为直角矩形,其所修饰的控件也应该为直角。
2. 变量定义
border_width: 蓝色带状阴影的宽度
border_radius: 带状阴影圆角的幅度
background_width: 背景图片的宽度
background_height: 背景图片的高度
二.背景图片使用
1. 获取背景图片的尺寸
QPixmap background =QPixmap(":/image/radius_border.png");
int background_width = background.width(); // 背景图片宽度
int background_height =background.height(); // 背景图片高度
2. 定义阴影带相关值
int border_width = 5; //阴影带的宽度
int border_radius = 5; // 阴影带圆角的半径
int corner_width = border_width + border_radius; // 阴影带4个转角的宽
int corner_height = border_width +border_radius; // 阴影带4个转角的高
int original_border = 1; // 控件原始边界宽度
3. 从左上角(leftTop)开始,顺时针截取(QPixmap对象的copy方法)4个转角与4个边
QPixmap leftTop =
background.copy(0, 0, corner_width,corner_height);
QPixmap top =
background.copy(corner_width, 0,background_width - 2 * corner_width, border_width);
QPixmap rightTop =
background.copy(background_width- corner_width, 0, corner_width, corner_height);
QPixmap right =
background.copy(background_width- border_width, corner_height, border_width,
background_height - 2 *corner_height);
QPixmap rightBottom =
background.copy(background_width - corner_width,background_height - corner_height,
corner_width, corner_height);
QPixmap bottom =
background.copy(corner_width, background_height -border_width, background_width –
2 * corner_width, border_width);
QPixmap leftBottom =
background.copy(0, background_height -corner_height, corner_width, corner_height);
QPixmap left =
background.copy(0, corner_height,border_width, background_height - 2 * corner_height);
4. 获取控件的位置,把上述截取的4角4边绘制在控件的边缘
/* 获取控件的位置 */
QRect rect =ui->lineEdit->geometry();
int startX = rect.left(); // 控件的起始X坐标
int endX = rect.right(); // 控件的终止X坐标
int startY = rect.top(); // 控件的起始Y坐标
int endY = rect.bottom(); // 控件的终止Y坐标
int width = rect.width(); // 控件宽度
int height = rect.height(); // 控件高度
/* 绘制4角4边 */
painter.drawPixmap(startX - border_width,startY - border_width, leftTop);
painter.drawPixmap(startX + border_radius,startY - border_width,
width - 2 *border_radius - original_border, border_width, top);
painter.drawPixmap(endX - border_radius,startY - border_width, rightTop);
painter.drawPixmap(endX, startY +border_radius, border_width,
height - 2 *border_radius - original_border, right);
painter.drawPixmap(endX - border_radius,endY - border_radius, rightBottom);
painter.drawPixmap(startX + border_radius,endY , width - 2 * border_radius - original_border,
border_width,bottom);
painter.drawPixmap(startX - border_width,endY - border_width, leftBottom);
painter.drawPixmap(startX - border_width,startY + border_radius, border_width,
height - 2 *border_radius - original_border, left);
二.工程源代码
2.1 工程结构如下图所示:
2.2 边界描述类
2.2.1 头文件 border.h
2.3 主窗口
2.3.1 头文件mainwindow.h
点击下载
最后要感谢的是刘典武大侠,本工程所采用的blue.css是从他的工程里面拿来的,3ks!
1. 名称定义
在Qt的控件中,加入类似CSS3的box-shodow的阴影效果。由于QSS不支持box-shodow属性,故而通过截图拼凑来模拟。
图1. radius_border.png
上图为我们需要准备的背景图(radius_border.png):
矩形区域(x2,y2,x5,y5)所内切包含的圆角矩形背景透明,之所以透明,是为了不遮掩住QT的控件背景,比如QLineEdit;
矩形区域(x1,y1,x6,y6)所内切包含的蓝色带状区域为控件的阴影;
矩形区域(x1,y1,x3,y3)所内切包含的蓝色扇环区域命名为leftTop;
矩形区域(x3,y1,x4,y2)所内切包含的蓝色矩形区域命名为top;
矩形区域(x4,y1,x6,y3)所内切包含的蓝色扇环区域命名为rightTop;
矩形区域(x5,y3,x6,y4)所内切包含的蓝色矩形区域命名为right;
矩形区域(x4,y4,x6,y6)所内切包含的蓝色扇环区域命名为rightBottom;
矩形区域(x3y5,x4,y6)所内切包含的蓝色矩形区域命名为bottom;
矩形区域(x1,y4,x3,y6)所内切包含的蓝色扇环区域命名为leftBottom
矩形区域(x1,y3,x2,y4)所内切包含的蓝色矩形区域命名为left;
注:当border_radius为0时,阴影即为直角矩形,其所修饰的控件也应该为直角。
2. 变量定义
border_width: 蓝色带状阴影的宽度
border_radius: 带状阴影圆角的幅度
background_width: 背景图片的宽度
background_height: 背景图片的高度
二.背景图片使用
1. 获取背景图片的尺寸
QPixmap background =QPixmap(":/image/radius_border.png");
int background_width = background.width(); // 背景图片宽度
int background_height =background.height(); // 背景图片高度
2. 定义阴影带相关值
int border_width = 5; //阴影带的宽度
int border_radius = 5; // 阴影带圆角的半径
int corner_width = border_width + border_radius; // 阴影带4个转角的宽
int corner_height = border_width +border_radius; // 阴影带4个转角的高
int original_border = 1; // 控件原始边界宽度
3. 从左上角(leftTop)开始,顺时针截取(QPixmap对象的copy方法)4个转角与4个边
QPixmap leftTop =
background.copy(0, 0, corner_width,corner_height);
QPixmap top =
background.copy(corner_width, 0,background_width - 2 * corner_width, border_width);
QPixmap rightTop =
background.copy(background_width- corner_width, 0, corner_width, corner_height);
QPixmap right =
background.copy(background_width- border_width, corner_height, border_width,
background_height - 2 *corner_height);
QPixmap rightBottom =
background.copy(background_width - corner_width,background_height - corner_height,
corner_width, corner_height);
QPixmap bottom =
background.copy(corner_width, background_height -border_width, background_width –
2 * corner_width, border_width);
QPixmap leftBottom =
background.copy(0, background_height -corner_height, corner_width, corner_height);
QPixmap left =
background.copy(0, corner_height,border_width, background_height - 2 * corner_height);
4. 获取控件的位置,把上述截取的4角4边绘制在控件的边缘
/* 获取控件的位置 */
QRect rect =ui->lineEdit->geometry();
int startX = rect.left(); // 控件的起始X坐标
int endX = rect.right(); // 控件的终止X坐标
int startY = rect.top(); // 控件的起始Y坐标
int endY = rect.bottom(); // 控件的终止Y坐标
int width = rect.width(); // 控件宽度
int height = rect.height(); // 控件高度
/* 绘制4角4边 */
painter.drawPixmap(startX - border_width,startY - border_width, leftTop);
painter.drawPixmap(startX + border_radius,startY - border_width,
width - 2 *border_radius - original_border, border_width, top);
painter.drawPixmap(endX - border_radius,startY - border_width, rightTop);
painter.drawPixmap(endX, startY +border_radius, border_width,
height - 2 *border_radius - original_border, right);
painter.drawPixmap(endX - border_radius,endY - border_radius, rightBottom);
painter.drawPixmap(startX + border_radius,endY , width - 2 * border_radius - original_border,
border_width,bottom);
painter.drawPixmap(startX - border_width,endY - border_width, leftBottom);
painter.drawPixmap(startX - border_width,startY + border_radius, border_width,
height - 2 *border_radius - original_border, left);
二.工程源代码
2.1 工程结构如下图所示:
2.2 边界描述类
2.2.1 头文件 border.h
#ifndef BORDER_H #define BORDER_H #include <QPixmap> #include <QPainter> class Border { public: Border(const char* bg); Border(const char* bg, int border_width, int border_radius, int original_border); void paintBorder(QPainter &painter, QRect &rect); ~Border(); private: QPixmap background; // 完整背景图 int background_width; // 背景图片宽度 int background_height; // 背景图片高度 int border_width; int border_radius; int original_border; int corner_width; int corner_height; QPixmap leftTop; QPixmap top; QPixmap rightTop; QPixmap right; QPixmap rightBottom; QPixmap bottom; QPixmap leftBottom; QPixmap left; QPixmap center; }; #endif // BORDER_H2.2.2 源文件border.cpp
#include "border.h" Border::Border(const char* bg):border_width(5), border_radius(5), original_border(1) { this->background = QPixmap(bg); } Border::Border(const char* bg, int border_width, int border_radius, int original_border) :border_width(5), border_radius(5), original_border(1) { this->background = QPixmap(bg); this->background_width = background.width(); // 背景图片宽度 this->background_height = background.height(); // 背景图片高度 this->border_width = border_width; this->border_radius = border_radius; this->original_border = original_border; this->corner_width = border_width + border_radius; this->corner_height = border_width + border_radius; /* 以顺时针方向旋转的边界 */ this->leftTop = background.copy(0, 0, corner_width, corner_height); this->top = background.copy(corner_width, 0, background_width - 2 * corner_width, border_width); this->rightTop = background.copy(background_width - corner_width, 0, corner_width, corner_height); this->right = background.copy(background_width - border_width, corner_height, border_width, this-> background_height - 2 * corner_height); this->rightBottom = background.copy(background_width - corner_width, background_height - corner_height, this-> corner_width, corner_height); this->bottom = background.copy(corner_width, background_height - border_width, this-> background_width - 2 * corner_width, border_width); this->leftBottom = background.copy(0, background_height - corner_height, corner_width, corner_height); this->left = background.copy(0, corner_height, border_width, background_height - 2 * corner_height); } Border::~Border() { } void Border::paintBorder(QPainter &painter, QRect& rect) { int startX = rect.left(); int endX = rect.right(); int startY = rect.top(); int endY = rect.bottom(); int width = rect.width(); int height = rect.height(); painter.drawPixmap(startX - border_width, startY - border_width, leftTop); painter.drawPixmap(startX + border_radius, startY - border_width, width - 2 * border_radius - original_border, border_width, top); painter.drawPixmap(endX - border_radius, startY - border_width, rightTop); painter.drawPixmap(endX, startY + border_radius, border_width, height - 2 * border_radius - original_border, right); painter.drawPixmap(endX - border_radius, endY - border_radius, rightBottom); painter.drawPixmap(startX + border_radius, endY , width - 2 * border_radius - original_border, border_width, bottom); painter.drawPixmap(startX - border_width, endY - border_width, leftBottom); painter.drawPixmap(startX - border_width, startY + border_radius, border_width, height - 2 * border_radius - original_border, left); }
2.3 主窗口
2.3.1 头文件mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTabWidget> #include <QMenu> #include <QMenuBar> #include <QAction> #include <QToolBar> #include "border.h" namespace Ui { class MainWindow; } /* * class MainWindow: 子类 * public QMainWindow:父类 */ class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private: Ui::MainWindow *ui; Border *border; protected: void paintEvent(QPaintEvent *event); bool eventFilter(QObject *watched,QEvent *event); bool event(QEvent *event); }; #endif // MAINWINDOW_H2.3.2 源文件mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QPushButton> #include <QMessageBox> #include <QGraphicsDropShadowEffect> #include <QDebug> #include <QPainter> #include <QMouseEvent> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 遍历子控件 QObjectList list = ui->centralWidget->children(); foreach (QObject *obj, list) { obj->installEventFilter(this); #if 0 qDebug() << obj->objectName(); // 控件名称 qDebug() << obj->metaObject()->className(); // 控件类名称 #endif char *className = (char *)obj->metaObject()->className(); // 去掉按钮的焦点 if(strcmp(className, "QPushButton") == 0) { QPushButton *button = qobject_cast<QPushButton*>(obj); button->setFocusPolicy(Qt::NoFocus); } } border = new Border(":/image/radius_border.png", 5, 5, 1); } MainWindow::~MainWindow() { delete ui; } /* * 在eventFilter函数中调用this->update(),则会触发该函数 */ void MainWindow::paintEvent(QPaintEvent *event) { QPainter painter(this); QObjectList list = ui->centralWidget->children(); foreach (QObject *obj, list) { char *className = (char *)obj->metaObject()->className(); if(strcmp(className, "QPushButton") == 0) { QPushButton *button = qobject_cast<QPushButton*>(obj); if(button->isDown()) { QRect rect = button->geometry(); border->paintBorder(painter, rect); } } if(strcmp(className, "QLineEdit") == 0) { QLineEdit *edit = qobject_cast<QLineEdit*>(obj); if(edit->hasFocus()) { QRect rect = edit->geometry(); border->paintBorder(painter, rect); } } } } /* * eventFilter针对某一控件事件的过滤,使用前需要在控件安装事件过滤器: * QObject->installEventFilter(this); */ bool MainWindow::eventFilter(QObject *watched, QEvent *event) { char *className = (char *)watched->metaObject()->className(); if(strcmp(className, "QPushButton") == 0 || strcmp(className, "QLineEdit") == 0) { this->update(); } return QWidget::eventFilter(watched, event); } /* * MainWindow的事件处理函数,例如鼠标点击事件:若鼠标点击在MainWindow窗口上面,则进入该函数。 * 如果鼠标点击事件在QLineEdit或者QPushButton上面,则不会进入。 */ bool MainWindow::event(QEvent* event) { switch(event->type()) { case QEvent::MouseButtonPress: qDebug() << "QEvent::MouseButtonPress"; break; default: break; } return QWidget::event(event); }2.4 主函数 main.cpp
#include "mainwindow.h" #include <QApplication> #include <QFile> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); QFile styleFile(":/image/blue.css"); styleFile.open(QIODevice::ReadOnly); QString setStyleSheet(styleFile.readAll());; a.setStyleSheet(setStyleSheet); return a.exec(); }
点击下载
最后要感谢的是刘典武大侠,本工程所采用的blue.css是从他的工程里面拿来的,3ks!
相关文章推荐
- jQuery 常用的代码片段
- jQuery--表单选择器
- jQuery插件windowScroll实现单屏滚动特效
- 基于jquery hover图片遮罩层滑动
- jQuery简介
- jQuery实现模拟marquee标签效果
- jQuery插件boxScroll实现图片轮播特效
- jQuery EasyUI简介
- 关于jQuery写插件及其演示
- jQuery插件boxScroll实现图片轮播特效
- jQuery实现模拟marquee标签效果
- jQuery插件windowScroll实现单屏滚动特效
- jQuery插件datalist实现很好看的input下拉列表
- 常用jQuery代码分享
- jquery获得当前html页面源码的方法
- jQuery实现自定义checkbox和radio样式
- jQuery实现自定义checkbox和radio样式
- 【2015.07.13周一~xxx】【读书笔记】【02】《jquery与javascript入门经典》
- jQuery Mobile 资料
- jquery checked