android on qt 之模拟jquery-mobile控件的box-shadow效果
来源:互联网 发布:centos安装内核源码 编辑:程序博客网 时间:2024/06/07 20:14
一.背景图片描述
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_OBJECTpublic: 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!
- android on qt 之模拟jquery-mobile控件的box-shadow效果
- CSS3属性之text-shadow和box-shadow(立体效果的实现)
- css:box-shadow的发光效果
- box-shadow阴影效果的使用
- css:box-shadow的发光效果
- box-shadow阴影效果
- jquery仿jquery mobile的select控件效果
- CSS3之box-shadow
- CSS之box-shadow
- css3之box-shadow
- css3 box-shadow发光效果
- css box-shadow效果演示
- css3 box-shadow 盒子效果
- css3的box-shadow属性实现进条效果
- CSS3 box-shadow实现纸张的曲线投影效果
- CSS实现跨浏览器的box-shadow盒阴影效果
- css3的box-shadow图层阴影效果
- css3 的 box-shadow
- HDU 2037 今年暑假不AC
- 图解C++、CoffeeScript 和 Ruby 的复杂度
- mysql 不常用函数用法
- 使用jmeter对websocket进行压力测试
- leetcode Anagrams
- android on qt 之模拟jquery-mobile控件的box-shadow效果
- MFC的对话框类CDialog
- go path.join
- 【Java语言基础】数据类型详解
- POJ 3427 Ecology tax(水~)
- 最优化学习笔记(五)牛顿法及拟牛顿法
- UITabBarController ---- 标签视图控制器
- Virtual machine 'win7' has terminated unexpectedly during startup解决
- HDU 1010 Tempter of the Bone