您的位置:首页 > 编程语言 > Qt开发

Qt使用QGraphicsView实现滑动窗体效果

2015-11-21 10:19 615 查看
源码已上传至CSDN,http://download.csdn.net/source/2808505

QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容。QGraphicsScene提供了QGraphicsItem的容器功能。通常与QGraphicsView一起使用来描述可视化图形项目。

QGraphicsScene提供了一个视图的场景,通过在这样一个场景之上加入不同的QGraphicsItem来构建视图。而QGraphicsView则提供了一个widget来显示QGraphicsScene的内容。所以要想成功构建一个视图,这三个元素缺一不可。

以下是一个QGraphicsView的例子,实现滑动的窗体效果,工具栏和图片均为场景中的Item。

#include <QtCore>

#include <QtGui>

#include <QtSvg>

/*程序中用到了svg格式的图片,所以需包含QtSvg*/

#define PAGE_COUNT 5

/*定义滑动窗体的窗体数*/







定义工具栏,NviBar继承自QGraphicsRectItem,用法与QGraphicsItem类似。



class NaviBar : public QObject, public QGraphicsRectItem

{

Q_OBJECT

public:

NaviBar();

void setPageOffset(qreal ofs);

signals:

void pageSelected(int page);

protected:

void mousePressEvent(QGraphicsSceneMouseEvent *event);

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);

private:

QList<QGraphicsSvgItem*> m_icons;

QGraphicsRectItem *m_cursor;

};







函数实现



#define ICON_SIZE 50

#define ICON_PAD 4

NaviBar::NaviBar()

: QGraphicsRectItem()

{

setRect(0, 0, 5 * ICON_SIZE, ICON_SIZE);

setPen(Qt::NoPen);

QStringList names;

names << "map" << "web" << "home" << "weather" << "contacts";

for (int i = 0; i < names.count(); ++i) {

QString fname = names[i];

fname.prepend(":/icons/");

fname.append("-page.svg");

QGraphicsSvgItem *icon = new QGraphicsSvgItem(fname);

icon->setParentItem(this);

const int dim = ICON_SIZE - ICON_PAD * 2;

qreal sw = dim / icon->boundingRect().width();

qreal sh = dim / icon->boundingRect().height();

icon->setTransform(QTransform().scale(sw, sh));

icon->setZValue(2);

m_icons << icon;

}

m_cursor = new QGraphicsRectItem;

m_cursor->setParentItem(this);

m_cursor->setRect(0, 0, ICON_SIZE, ICON_SIZE);

m_cursor->setZValue(1);

m_cursor->setPen(Qt::NoPen);

m_cursor->setBrush(QColor(Qt::white));

m_cursor->setOpacity(0.6);

}

void NaviBar::setPageOffset(qreal ofs)

{

m_cursor->setPos(ofs * ICON_SIZE, 0);

for (int i = 0; i < m_icons.count(); ++i) {

int y = (i == static_cast<int>(ofs + 0.5)) ? ICON_PAD : ICON_PAD * 2;

m_icons[i]->setPos(i * ICON_SIZE + ICON_PAD, y);

m_icons[i]->setOpacity(1);

}

}

void NaviBar::mousePressEvent(QGraphicsSceneMouseEvent *event)

{

emit pageSelected(static_cast<int>(event->pos().x() / ICON_SIZE));

}

void NaviBar::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)

{

painter->setBrush(Qt::white);

painter->setOpacity(0.2);

painter->drawRect(option->rect.adjusted(-20, ICON_PAD, 20, 0));

}









定义视图



class ParallaxHome: public QGraphicsView

{

Q_OBJECT

public:

QGraphicsScene m_scene;

NaviBar *m_naviBar;

QGraphicsPixmapItem *m_wallpaper;

QTimeLine m_pageAnimator;

qreal m_pageOffset;

QList<QGraphicsPixmapItem*> m_items;

QList<QPointF> m_positions;

public:

ParallaxHome(QWidget *parent = 0)

: QGraphicsView(parent)

, m_pageOffset(-2) {

setupScene();

setScene(&m_scene);

setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

setFrameShape(QFrame::NoFrame);

setWindowTitle("Parallax Home");

connect(&m_pageAnimator, SIGNAL(frameChanged(int)), SLOT(shiftPage(int)));

m_pageAnimator.setDuration(500);

m_pageAnimator.setFrameRange(0, 100);

m_pageAnimator.setCurveShape(QTimeLine::EaseInCurve);

pageChanged(static_cast<int>(m_pageOffset));

}

signals:

void pageChanged(int page);

public slots:

void slideRight() {

if (m_pageAnimator.state() != QTimeLine::NotRunning)

return;

int edge = -(m_pageOffset - 1);

if (edge < PAGE_COUNT)

slideBy(-1);

}

void slideLeft() {

if (m_pageAnimator.state() != QTimeLine::NotRunning)

return;

if (m_pageOffset < 0)

slideBy(1);

}

void slideBy(int dx) {

int start = m_pageOffset * 1000;

int end = (m_pageOffset + dx) * 1000;

m_pageAnimator.setFrameRange(start, end);

m_pageAnimator.start();

}

void choosePage(int page) {

if (m_pageAnimator.state() != QTimeLine::NotRunning)

return;

if (static_cast<int>(-m_pageOffset) == page)

return;

slideBy(-page - m_pageOffset);

}

private slots:

void shiftPage(int frame) {

int ww = width();

int hh = height() - m_naviBar->rect().height();

int oldPage = static_cast<int>(-m_pageOffset);

m_pageOffset = static_cast<qreal>(frame) / qreal(1000);

int newPage = static_cast<int>(-m_pageOffset);

m_naviBar->setPageOffset(-m_pageOffset);

if (oldPage != newPage)

emit pageChanged(newPage);

int ofs = m_pageOffset * ww;

for (int i = 0; i < m_items.count(); ++i) {

QPointF pos = m_positions[i];

QPointF xy(pos.x() * ww, pos.y() * hh);

m_items[i]->setPos(xy + QPointF(ofs, 0));

}

int center = m_wallpaper->pixmap().width() / 2;

const int parallax = 3;

int base = center - (ww / 2) - (PAGE_COUNT >> 1) * (ww / parallax);

int wofs = base - m_pageOffset * ww / parallax;

m_wallpaper->setPos(-wofs, 0);

}

protected:

void resizeEvent(QResizeEvent *event) {

Q_UNUSED(event);

layoutScene();

}

void keyPressEvent(QKeyEvent *event) {

if (event->key() == Qt::Key_Right)

slideRight();

if (event->key() == Qt::Key_Left)

slideLeft();

event->accept();

}

private:

void layoutScene() {

int ww = width();

int hh = height();

m_scene.setSceneRect(0, 0, PAGE_COUNT * ww - 1, hh - 1);

centerOn(ww / 2, hh / 2);

int nw = m_naviBar->rect().width();

int nh = m_naviBar->rect().height();

m_naviBar->setPos((ww - nw) / 2, hh - nh);

shiftPage(m_pageOffset * 1000);

}

void setupScene() {

qsrand(QTime::currentTime().second());

QStringList names;

names << "brownies" << "cookies" << "mussels" << "pizza" << "sushi";

names << "chocolate" << "fish" << "pasta" << "puding" << "trouts";

for (int i = 0; i < PAGE_COUNT * 2; ++i) {

QString fname = names[i];

fname.prepend(":/images/");

fname.append(".jpg");

QPixmap pixmap(fname);

pixmap = pixmap.scaledToWidth(200);

QGraphicsPixmapItem *item = m_scene.addPixmap(pixmap);

m_items << item;

qreal x = (i >> 1) + (qrand() % 30) / 100.0;

qreal y = (i & 1) / 2.0 + (qrand() % 20) / 100.0;

m_positions << QPointF(x, y);

item->setZValue(1);

}

m_naviBar = new NaviBar;

m_scene.addItem(m_naviBar);

m_naviBar->setZValue(2);

connect(m_naviBar, SIGNAL(pageSelected(int)), SLOT(choosePage(int)));

m_wallpaper = m_scene.addPixmap(QPixmap(":/icons/surfacing.png"));

m_wallpaper->setZValue(0);

m_scene.setItemIndexMethod(QGraphicsScene::NoIndex);

}

};







main函数



#include "parallaxhome.moc"

int main(int argc, char *argv[])

{

QApplication app(argc, argv);

ParallaxHome w;

w.resize(360, 640);

w.show();

return app.exec();

}


http://blog.csdn.net/huihui1988/article/details/5725955
FROM: http://www.cnblogs.com/findumars/p/4973174.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: