×
Namespaces

Variants
Actions
(Difference between revisions)

Code Example for SlidingStackedWidget class in Qt

From Nokia Developer Wiki
Jump to: navigation, search
jimgilmour1 (Talk | contribs)
m (moderator: code format missed first time edit)
hamishwillee (Talk | contribs)
m (Hamishwillee - Change to use new video player which works with Lumia 920 and other mobile browsers)
 
(12 intermediate revisions by 4 users not shown)
Line 1: Line 1:
__NOTOC__
+
[[Category:Qt]][[Category:Code Examples]][[Category:MeeGo Harmattan]][[Category:Symbian]][[Category:UI]][[Category:Qt C++ UI]]
__NOEDITSECTION__
+
{{ArticleMetaData <!-- v1.2 -->
{{CodeSnippet
+
|sourcecode= [[Media:SampleSlidingStackedWidget.zip]]
|id=...
+
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
|platform=S60 5th Edition
+
 
|devices= 5800 XpressMusic
 
|devices= 5800 XpressMusic
|category=Qt for Symbian, Qt, Code Examples
+
|sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Nokia Qt SDK 1.1]) -->
|subcategory=QStackedWidget, QAnimation
+
|platform= S60 5th Edition
|creationdate=March 23th, 2010
+
|devicecompatability= <!-- Compatible devices (e.g.: All* (must have GPS) ) -->
|keywords=QStackedWidget, QAnimation, animation, Tab Widget
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
 +
|signing= <!-- Empty or one of Self-Signed, DevCert, Manufacturer -->
 +
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
 +
|keywords= QStackedWidget, QAnimation, animation, Tab Widget
 +
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
 +
|translated-by= <!-- [[User:XXXX]] -->
 +
|translated-from-title= <!-- Title only -->
 +
|translated-from-id= <!-- Id of translated revision -->
 +
|review-by= <!-- After re-review: [[User:username]] -->
 +
|review-timestamp= <!-- After re-review: YYYYMMDD -->
 +
|update-by= <!-- After significant update: [[User:username]]-->
 +
|update-timestamp= <!-- After significant update: YYYYMMDD -->
 +
|creationdate= March 23th, 2010
 +
|author= [[User:Juergenm]]
 
}}
 
}}
[[Category:Code Examples]][[Category:Qt for Symbian]][[Category:Qt]]
 
  
 
==Overview==
 
==Overview==
  
This Article gives a full Qt Creator Code Example Project for the SlidingStackedWidget class as described in the article [[Extending_QStackedWidget_for_sliding_page_animations_in_Qt]]
+
This Article gives a full Qt Creator Code Example Project for the QStackedWidget class as described in the article [[Extending QStackedWidget for sliding page animations in Qt]]
  
 
This code example can be self-signed.
 
This code example can be self-signed.
 +
 +
==Postconditions==
 +
 +
When successfully building and running this code example, the result should be as illustrated in the following clip:
 +
 +
<mediaplayer>http://www.youtube.com/watch?v=9MXJlgWJfc0</mediaplayer>
 +
  
 
==Source files==
 
==Source files==
Line 24: Line 42:
 
'''SlidingStackedWidget.cpp'''
 
'''SlidingStackedWidget.cpp'''
  
<code cpp>
+
<code cpp-qt>
 
#include "SlidingStackedWidget.h"
 
#include "SlidingStackedWidget.h"
  
Line 105: Line 123:
  
  
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) {
+
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) {
  
 
         if (m_active) {
 
         if (m_active) {
Line 225: Line 243:
  
 
'''SlidingStackedWidget.h'''
 
'''SlidingStackedWidget.h'''
<code cpp>
+
<code cpp-qt>
 
#ifndef SLIDINGSTACKEDWIDGET_H
 
#ifndef SLIDINGSTACKEDWIDGET_H
 
#define SLIDINGSTACKEDWIDGET_H
 
#define SLIDINGSTACKEDWIDGET_H
Line 306: Line 324:
  
 
'''MainWindow.h'''
 
'''MainWindow.h'''
<code cpp>
+
<code cpp-qt>
  
 
#ifndef MAINWINDOW_H
 
#ifndef MAINWINDOW_H
Line 363: Line 381:
 
'''MainWindow.cpp'''
 
'''MainWindow.cpp'''
  
<code cpp>
+
<code cpp-qt>
  
 
#include "MainWindow.h"
 
#include "MainWindow.h"
Line 492: Line 510:
 
'''main.cpp''
 
'''main.cpp''
  
<code cpp>
+
<code cpp-qt>
 
#include <QtGui/QApplication>
 
#include <QtGui/QApplication>
 
#include "MainWindow.h"
 
#include "MainWindow.h"
Line 530: Line 548:
 
</code>
 
</code>
  
==Postconditions==
 
 
When successfully building and running this code example, the result should look like these screenshots.
 
In this example, the red marked area is used by four stacked widgets, that are sliding smoothly in and out:
 
 
[[File:SampleSlidingStackedWidget_Screenshots.jpg]]
 
  
 
==Test application==
 
==Test application==

Latest revision as of 05:57, 30 January 2013

Article Metadata
Code ExampleTested with
Devices(s): 5800 XpressMusic
Compatibility
Platform(s): S60 5th Edition
Symbian
Article
Keywords: QStackedWidget, QAnimation, animation, Tab Widget
Created: juergenm (23 Mar 2010)
Last edited: hamishwillee (30 Jan 2013)

Contents

[edit] Overview

This Article gives a full Qt Creator Code Example Project for the QStackedWidget class as described in the article Extending QStackedWidget for sliding page animations in Qt

This code example can be self-signed.

[edit] Postconditions

When successfully building and running this code example, the result should be as illustrated in the following clip:

The media player is loading...


[edit] Source files

Complete Source files and header files are part or the attached ZIP archive, that also includes the Qt Creator .pro file.

SlidingStackedWidget.cpp

#include "SlidingStackedWidget.h"
 
 
SlidingStackedWidget::SlidingStackedWidget(QWidget *parent)
: QStackedWidget(parent)
{
if (parent!=0) {
m_mainwindow=parent;
}
else {
m_mainwindow=this;
qDebug()<<"ATTENTION: untested mainwindow case !";
}
//parent should not be 0; not tested for any other case yet !!
#ifdef Q_OS_SYMBIAN
#ifndef __S60_50__
qDebug()<< "WARNING: ONLY TESTED AND 5TH EDITION";
#endif //__S60_50__
#endif //Q_OS_SYMBIAN
//Now, initialize some private variables with default values
m_vertical=false;
//setVerticalMode(true);
m_speed=500;
m_animationtype = QEasingCurve::OutBack; //check out the QEasingCurve documentation for different styles
m_now=0;
m_next=0;
m_wrap=false;
m_pnow=QPoint(0,0);
m_active=false;
}
 
 
SlidingStackedWidget::~SlidingStackedWidget(){
}
 
void SlidingStackedWidget::setVerticalMode(bool vertical) {
m_vertical=vertical;
}
 
void SlidingStackedWidget::setSpeed(int speed) {
m_speed = speed;
}
 
void SlidingStackedWidget::setAnimation(enum QEasingCurve::Type animationtype) {
m_animationtype = animationtype;
}
 
void SlidingStackedWidget::setWrap(bool wrap) {
m_wrap=wrap;
}
 
void SlidingStackedWidget::slideInNext() {
int now=currentIndex();
if (m_wrap||(now<count()-1))
// count is inherit from QStackedWidget
slideInIdx(now+1);
}
 
 
void SlidingStackedWidget::slideInPrev() {
int now=currentIndex();
if (m_wrap||(now>0))
slideInIdx(now-1);
}
 
void SlidingStackedWidget::slideInIdx(int idx, enum t_direction direction) {
//int idx, t_direction direction=AUTOMATIC
if (idx>count()-1) {
direction=m_vertical ? TOP2BOTTOM : RIGHT2LEFT;
idx=(idx)%count();
}
else if (idx<0) {
direction= m_vertical ? BOTTOM2TOP: LEFT2RIGHT;
idx=(idx+count())%count();
}
slideInWgt(widget ( idx ),direction);
//widget() is a function inherited from QStackedWidget
}
 
 
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) {
 
if (m_active) {
return; // at the moment, do not allow re-entrance before an animation is completed.
//other possibility may be to finish the previous animation abrupt, or
//to revert the previous animation with a counter animation, before going ahead
//or to revert the previous animation abrupt
//and all those only, if the newwidget is not the same as that of the previous running animation.
}
else m_active=true;
 
enum t_direction directionhint;
int now=currentIndex(); //currentIndex() is a function inherited from QStackedWidget
int next=indexOf(newwidget);
if (now==next) {
m_active=false;
return;
}
else if (now<next){
directionhint=m_vertical ? TOP2BOTTOM : RIGHT2LEFT;
}
else {
directionhint=m_vertical ? BOTTOM2TOP : LEFT2RIGHT;
}
if (direction == AUTOMATIC) {
direction=directionhint;
}
//NOW....
//calculate the shifts
 
int offsetx=frameRect().width(); //inherited from mother
int offsety=frameRect().height();//inherited from mother
 
//the following is important, to ensure that the new widget
//has correct geometry information when sliding in first time
widget(next)->setGeometry ( 0, 0, offsetx, offsety );
 
if (direction==BOTTOM2TOP) {
offsetx=0;
offsety=-offsety;
}
else if (direction==TOP2BOTTOM) {
offsetx=0;
//offsety=offsety;
}
else if (direction==RIGHT2LEFT) {
offsetx=-offsetx;
offsety=0;
}
else if (direction==LEFT2RIGHT) {
//offsetx=offsetx;
offsety=0;
}
//re-position the next widget outside/aside of the display area
QPoint pnext=widget(next)->pos();
QPoint pnow=widget(now)->pos();
m_pnow=pnow;
 
widget(next)->move(pnext.x()-offsetx,pnext.y()-offsety);
//make it visible/show
widget(next)->show();
widget(next)->raise();
 
//animate both, the now and next widget to the side, using animation framework
QPropertyAnimation *animnow = new QPropertyAnimation(widget(now), "pos");
 
animnow->setDuration(m_speed);
animnow->setEasingCurve(m_animationtype);
animnow->setStartValue(QPoint(pnow.x(), pnow.y()));
animnow->setEndValue(QPoint(offsetx+pnow.x(), offsety+pnow.y()));
QPropertyAnimation *animnext = new QPropertyAnimation(widget(next), "pos");
animnext->setDuration(m_speed);
animnext->setEasingCurve(m_animationtype);
animnext->setStartValue(QPoint(-offsetx+pnext.x(), offsety+pnext.y()));
animnext->setEndValue(QPoint(pnext.x(), pnext.y()));
 
QParallelAnimationGroup *animgroup = new QParallelAnimationGroup;
 
animgroup->addAnimation(animnow);
animgroup->addAnimation(animnext);
 
QObject::connect(animgroup, SIGNAL(finished()),this,SLOT(animationDoneSlot()));
m_next=next;
m_now=now;
m_active=true;
animgroup->start();
 
//note; the rest is done via a connect from the animation ready;
//animation->finished() provides a signal when animation is done;
//so we connect this to some post processing slot,
//that we implement here below in animationDoneSlot.
}
 
 
void SlidingStackedWidget::animationDoneSlot(void) {
//when ready, call the QStackedWidget slot setCurrentIndex(int)
setCurrentIndex(m_next); //this function is inherit from QStackedWidget
//then hide the outshifted widget now, and (may be done already implicitely by QStackedWidget)
widget(m_now)->hide();
//then set the position of the outshifted widget now back to its original
widget(m_now)->move(m_pnow);
//so that the application could also still call the QStackedWidget original functions/slots for changings
//widget(m_now)->update();
//setCurrentIndex(m_next); //this function is inherit from QStackedWidget
m_active=false;
emit animationFinished();
}
 
 
 
/* REFERENCES
 
http://doc.trolltech.com/4.6/animation-overview.html#easing-curves
http://doc.trolltech.com/4.6/qpropertyanimation.html
http://doc.trolltech.com/4.6/qanimationgroup.html
 
*/

SlidingStackedWidget.h

#ifndef SLIDINGSTACKEDWIDGET_H
#define SLIDINGSTACKEDWIDGET_H
 
#include <QStackedWidget>
 
#include <QtGui>
#include <QWidget>
#include <QDebug>
#include <QEasingCurve>
 
/*!
Description
SlidingStackedWidget is a class that is derived from QtStackedWidget
and allows smooth side shifting of widgets, in addition
to the original hard switching from one to another as offered by
QStackedWidget itself.
*/

 
class SlidingStackedWidget : public QStackedWidget
{
Q_OBJECT
 
public:
//! This enumeration is used to define the animation direction
enum t_direction {
LEFT2RIGHT,
RIGHT2LEFT,
TOP2BOTTOM,
BOTTOM2TOP,
AUTOMATIC
};
 
//! The Constructor and Destructor
SlidingStackedWidget(QWidget *parent);
~SlidingStackedWidget(void);
 
 
public slots:
//! Some basic settings API
void setSpeed(int speed); //animation duration in milliseconds
void setAnimation(enum QEasingCurve::Type animationtype); //check out the QEasingCurve documentation for different styles
void setVerticalMode(bool vertical=true);
void setWrap(bool wrap); //wrapping is related to slideInNext/Prev;it defines the behaviour when reaching last/first page
 
//! The Animation / Page Change API
void slideInNext();
void slideInPrev();
void slideInIdx(int idx, enum t_direction direction=AUTOMATIC);
 
 
signals:
//! this is used for internal purposes in the class engine
void animationFinished(void);
 
protected slots:
//! this is used for internal purposes in the class engine
void animationDoneSlot(void);
 
protected:
//! this is used for internal purposes in the class engine
void slideInWgt(QWidget * widget, enum t_direction direction=AUTOMATIC);
 
QWidget *m_mainwindow;
 
int m_speed;
enum QEasingCurve::Type m_animationtype;
bool m_vertical;
int m_now;
int m_next;
bool m_wrap;
QPoint m_pnow;
bool m_active;
 
QList<QWidget*> blockedPageList;
};
 
#endif // SLIDINGSTACKEDWIDGET_H

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QtGui/QMainWindow>
 
#include <QtGui>
#include <QPushButton>
#include <QCheckBox>
#include <QListWidget>
#include <QSlider>
 
 
 
#include "SlidingStackedWidget.h"
 
class MainWindow : public QMainWindow
{
Q_OBJECT
 
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
 
protected:
void createGuiControlComponents();
void createMainLayout();
void createSubSlidingWidgets();
void createConnections();
void createSlidingStackedWidget();
QPushButton *buttonNext;
QPushButton *buttonPrev;
QCheckBox *checkWrap;
QCheckBox *checkVertical;
QSlider *slideSpeed;
QComboBox *listAll;
QLabel *speedLabel;
QLCDNumber *speedDisplay;
 
SlidingStackedWidget *slidingStacked;
QVBoxLayout *mainLayout;
QGridLayout *controlPaneLayout;
QWidget *centralWidget;
QWidget *slideWidget1;
QWidget *slideWidget2;
QWidget *slideWidget3;
QWidget *slideWidget4;
 
int animTime;
};
 
#endif // MAINWINDOW_H

MainWindow.cpp

#include "MainWindow.h"
 
 
// The Constructor calls the subfunctions for creation of the sample application
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
animTime=500;
createGuiControlComponents();
createSubSlidingWidgets();
createSlidingStackedWidget();
createMainLayout();
createConnections();
}
 
MainWindow::~MainWindow() {
 
}
 
void MainWindow::createGuiControlComponents() {
int _min=500;
int _max=1500;
animTime=(_min+_max)>>1;
 
buttonNext = new QPushButton(tr("Next"));
buttonPrev = new QPushButton(tr("Prev"));
checkWrap = new QCheckBox(tr("Wrap"));
checkVertical = new QCheckBox(tr("Vertical"));
 
listAll = new QComboBox();
listAll->addItem(tr("Page 1"));
listAll->addItem(tr("Page 2"));
listAll->addItem(tr("Page 3"));
listAll->addItem(tr("Page 4"));
listAll->setMinimumHeight ( 40 );
 
speedLabel = new QLabel(tr("Anim. Time:"));
speedDisplay= new QLCDNumber();
 
slideSpeed = new QSlider(Qt::Horizontal);
slideSpeed->setMinimum(_min);
slideSpeed->setMaximum(_max);
 
//initialize slider and its display
slideSpeed->setValue(animTime);
speedDisplay->display(animTime);
}
 
void MainWindow::createMainLayout() {
centralWidget=new QWidget(this);
mainLayout=new QVBoxLayout();
centralWidget->setLayout(mainLayout);
controlPaneLayout=new QGridLayout();
mainLayout->addWidget(slidingStacked);
mainLayout->addLayout(controlPaneLayout);
int row;
row=1;
controlPaneLayout->addWidget(buttonPrev,row,1,1,1);
controlPaneLayout->addWidget(buttonNext,row,2,1,1);
controlPaneLayout->addWidget(checkWrap,++row,1,1,1);
controlPaneLayout->addWidget(checkVertical,row,2,1,1);
controlPaneLayout->addWidget(speedLabel,++row,1,1,1);
controlPaneLayout->addWidget(speedDisplay,row,2,1,1);
controlPaneLayout->addWidget(slideSpeed,++row,1,1,2);
controlPaneLayout->addWidget(listAll,++row,1,1,2);
 
this->setCentralWidget(centralWidget);
}
 
void MainWindow::createSubSlidingWidgets() {
slideWidget1=new QWidget();
slideWidget2=new QWidget();
slideWidget3=new QWidget();
slideWidget4=new QWidget();
QVBoxLayout *slideWidget1layout=new QVBoxLayout();
slideWidget1->setLayout(slideWidget1layout);
QVBoxLayout *slideWidget2layout=new QVBoxLayout();
slideWidget2->setLayout(slideWidget2layout);
QVBoxLayout *slideWidget3layout=new QVBoxLayout();
slideWidget3->setLayout(slideWidget3layout);
QVBoxLayout *slideWidget4layout=new QVBoxLayout();
slideWidget4->setLayout(slideWidget4layout);
QPushButton *b11=new QPushButton("Qt");
slideWidget1layout->addWidget(b11);
QPushButton *b12=new QPushButton("is cool !");
slideWidget1layout->addWidget(b12);
 
QPushButton *b21=new QPushButton("Cool");
slideWidget2layout->addWidget(b21);
QPushButton *b22=new QPushButton("is Qt !");
slideWidget2layout->addWidget(b22);
 
QPushButton *b31=new QPushButton("Isn't");
slideWidget3layout->addWidget(b31);
QPushButton *b32=new QPushButton("Qt cool ?");
slideWidget3layout->addWidget(b32);
 
QPushButton *b41=new QPushButton("How cool");
slideWidget4layout->addWidget(b41);
QPushButton *b42=new QPushButton("is Qt !");
slideWidget4layout->addWidget(b42);
}
 
void MainWindow::createSlidingStackedWidget() {
slidingStacked= new SlidingStackedWidget(this);
slidingStacked->addWidget(slideWidget1);
slidingStacked->addWidget(slideWidget2);
slidingStacked->addWidget(slideWidget3);
slidingStacked->addWidget(slideWidget4);
slidingStacked->setSpeed(animTime);
}
 
void MainWindow::createConnections() {
QObject::connect(buttonNext,SIGNAL(pressed()),slidingStacked,SLOT(slideInNext()));
QObject::connect(buttonPrev,SIGNAL(pressed()),slidingStacked,SLOT(slideInPrev()));
QObject::connect(checkWrap,SIGNAL(clicked(bool)),slidingStacked,SLOT(setWrap(bool)));
QObject::connect(checkVertical,SIGNAL(clicked(bool)),slidingStacked,SLOT(setVerticalMode(bool)));
QObject::connect(slideSpeed,SIGNAL(valueChanged(int)),slidingStacked,SLOT(setSpeed(int)));
QObject::connect(slideSpeed,SIGNAL(valueChanged(int)),speedDisplay,SLOT(display(int)));
QObject::connect(listAll,SIGNAL(currentIndexChanged(int)),slidingStacked,SLOT(slideInIdx(int)));
}


'main.cpp

#include <QtGui/QApplication>
#include "MainWindow.h"
 
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
 
#ifdef Q_OS_SYMBIAN
w.showMaximized();
#else
w.resize(360, 504);
w.show();
#endif
 
return a.exec();
}


SampleSlidingStackedWidget.pro

# -------------------------------------------------
# Project created by QtCreator 2010-03-21T15:45:08
# -------------------------------------------------
TARGET = SampleSlidingStackedWidget
TEMPLATE = app
SOURCES += main.cpp \
MainWindow.cpp \
SlidingStackedWidget.cpp
HEADERS += MainWindow.h \
SlidingStackedWidget.h


[edit] Test application

Here the complete Sample Code Archive for download:

File:SampleSlidingStackedWidget.zip

This page was last modified on 30 January 2013, at 05:57.
269 page views in the last 30 days.
×