Qt使用QGraphicsView实现滑动窗体效果 .
2016-03-27 00:21
483 查看
源码已上传至CSDN,http://download.csdn.net/source/2808505
QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容。QGraphicsScene提供了QGraphicsItem的容器功能。通常与QGraphicsView一起使用来描述可视化图形项目。
QGraphicsScene提供了一个视图的场景,通过在这样一个场景之上加入不同的QGraphicsItem来构建视图。而QGraphicsView则提供了一个widget来显示QGraphicsScene的内容。所以要想成功构建一个视图,这三个元素缺一不可。
以下是一个QGraphicsView的例子,实现滑动的窗体效果,工具栏和图片均为场景中的Item。
[cpp]
view plain
copy
print?
#include <QtCore>
#include <QtGui>
#include <QtSvg>
/*程序中用到了svg格式的图片,所以需包含QtSvg*/
#define PAGE_COUNT 5
/*定义滑动窗体的窗体数*/
函数实现
[cpp]
view plain
copy
print?
#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));
}
main函数
[cpp]
view plain
copy
print?
#include "parallaxhome.moc"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ParallaxHome w;
w.resize(360, 640);
w.show();
return app.exec();
}
#include "parallaxhome.moc"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ParallaxHome w;
w.resize(360, 640);
w.show();
return app.exec();
}
效果图
FROM: http://blog.csdn.net/huihui1988/article/details/5725955
QGraphicsView用来显示一个滚动视图区的QGraphicsScene内容。QGraphicsScene提供了QGraphicsItem的容器功能。通常与QGraphicsView一起使用来描述可视化图形项目。
QGraphicsScene提供了一个视图的场景,通过在这样一个场景之上加入不同的QGraphicsItem来构建视图。而QGraphicsView则提供了一个widget来显示QGraphicsScene的内容。所以要想成功构建一个视图,这三个元素缺一不可。
以下是一个QGraphicsView的例子,实现滑动的窗体效果,工具栏和图片均为场景中的Item。
[cpp]
view plain
copy
print?
#include <QtCore>
#include <QtGui>
#include <QtSvg>
/*程序中用到了svg格式的图片,所以需包含QtSvg*/
#define PAGE_COUNT 5
/*定义滑动窗体的窗体数*/
[cpp] view plain copy print? 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; }; 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; };
函数实现
[cpp]
view plain
copy
print?
#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));
}
[cpp] view plain copy print? 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); } }; 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函数
[cpp]
view plain
copy
print?
#include "parallaxhome.moc"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ParallaxHome w;
w.resize(360, 640);
w.show();
return app.exec();
}
#include "parallaxhome.moc"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ParallaxHome w;
w.resize(360, 640);
w.show();
return app.exec();
}
效果图
FROM: http://blog.csdn.net/huihui1988/article/details/5725955
相关文章推荐
- Qt5.2加载百度地图进行相关操作
- qt学习笔记(五) QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果
- qt 调用百度api 之 Qt 与 Html交互
- QTP/UFT自动化框架分析,QTP缺点与改进。
- qt事件分析
- QT5学习:窗口布局测试
- Windows下Qt4的安装方法及安装包(百度云)下载
- Qt乱码问题>>
- QT5 乱码问题
- 生成QT跨平台可执行文件
- 如何让ARM板启动的时候就运行自己的QT程序
- OK335xS tmp75 Qt 温度读取
- 将Qt、OpenGL、GLSL以及Qt的Graphics-View框架组合
- Qt的Graphics-View框架和OpenGL结合详解
- QT 的 Graphics View 系统
- qt中使用opencv处理图片 QImage 和 IplImage 相互之间转换问题
- Qt:Drag-Drop操作在QGraphicsView及Model/View框架下的实现
- Qt浅谈之十八:GraphicsView框架事件处理
- Qt浅谈之十七:飞舞的蝴蝶(GraphicsView框架)
- QTableWidget的用法总结