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_H
2.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_H
2.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!

0 0
原创粉丝点击