QT C++ Graphics Programming Video Tutorial|Simple Pendulum Simulation
Rate this article
0 out of 5
In This Video Tutorial we will show you how to Develop a Simple Pendulum Simulation program in QT C++. Video simulation program in QT C++.

Simple Pendulum is one of the most common experiment conducted by students to find the acceleration due to gravity at the place in the LAB.   Simulating oscillation of a simple pendulum is one of the simpler task in programming thereby a student will be able to gain valuable concepts about computer simulation. This tutorial just attempted the same here.

Watch the video from the link below..




Main Source Code

Multithread.h

#ifndef MULTITHREAD_H
#define MULTITHREAD_H
#include <QObject>
#include <QMutex>
#include <QWaitCondition>

class MultiThread : public QObject
{
    Q_OBJECT


public:
     MultiThread(QObject *parent = 0);
     void requestThread();
     void abort();
     void resume();


private:


         bool _abort;
         bool _working;
         QMutex mutex;
         QWaitCondition pauseContd;



signals:

         void multithreadRequested();
         void valueChanged(const QString &value);
         void value(int a);
         void finished();
         void resumed();

     public slots:

         void doMultiThread();

};
#endif // MULTITHREAD_H

Multithread.cpp

#include "multithread.h"
#include <QTimer>
#include <QEventLoop>
#include "simplependulum.h"
#include <QThread>
#include <QDebug>
//SimplePendulum *pendulum;
MultiThread::MultiThread(QObject *parent) :
    QObject(parent)
{
    _working =false;
    _abort = false;
    //pendulum=new SimplePendulum;

}

void MultiThread::requestThread()
{
    mutex.lock();
    _working = true;
    _abort = false;
    qDebug()<<thread()->currentThreadId();
    mutex.unlock();

    emit multithreadRequested();
}

void MultiThread::abort()
{
    mutex.lock();
    if (_working) {
        _abort = true;
        qDebug()<<thread()->currentThreadId();
    }
    mutex.unlock();
}
void MultiThread::resume()
{
mutex.lock();
if(!_working)
{
_abort = true;
qDebug()<<thread()->currentThreadId();
}
mutex.unlock();
pauseContd.wakeAll();
emit resume();


}

void MultiThread::doMultiThread()
{
    qDebug()<<thread()->currentThreadId();
    long int iCounter=0;
    while(true)
    {
        iCounter++;
        int a=iCounter;
        if(a!=0)
        {
            emit value(a);

        }

        /*else if(a==3)
        {
            emit value(a);
        }
        else if(a==4)
        {
            emit value(a);
        }
        else if(a==5)
        {
            emit value(a);
        }
        else if(a==6)
        {
            emit value(a);
        }
        else if(a==7)
        {
            emit value(a);
        }
        else if(a==8)
        {
            emit value(a);
        }
        else if(a==9)
        {
            emit value(a);
        }*/
        mutex.lock();
        bool abort = _abort;
        mutex.unlock();

        if (abort)
        {
            qDebug()<<thread()->currentThreadId();
            break;
        }

        QEventLoop loop;
        QTimer::singleShot(1000, &loop, SLOT(quit()));
        loop.exec();
        emit valueChanged(QString::number(iCounter));
    }
mutex.lock();
_working = false;
mutex.unlock();

qDebug()<<thread()->currentThreadId();

emit finished();
}

simplependulum.h

#ifndef SIMPLEPENDULUM_H
#define SIMPLEPENDULUM_H

#include <QMainWindow>
//#include <QThread>
//#include "multithread.h"
#include <QMessageBox>

namespace Ui {
    class SimplePendulum;
}

class SimplePendulum : public QMainWindow {
    Q_OBJECT
public:
    QMessageBox msg;
//    int m_width;
//    int m_Height;
//    int m_NoOfRows;
//    int m_NoOfPendulumRows;
//    int m_NoOfCols;
//    int m_XOffset; //Offset from which drawing start
//    int m_YOffset;
    void Initialdisplay(int b);
    void display1(int c);
    void abort();


    SimplePendulum(QWidget *parent = 0);
    ~SimplePendulum();

protected:
    void changeEvent(QEvent *e);
    void paintEvent(QPaintEvent *);
    void Initialize();


private:
    Ui::SimplePendulum *ui;
    //QThread *thread;
    //MultiThread *multithread;


private slots:
    void on_actionPause_2_activated();
    void on_actionStart_2_activated();
    void on_pushButton_Reset_clicked();
    void on_pushButton_clicked();
    void on_actionResume_activated();
    void on_actionPause_activated();
    void on_actionStart_activated();
    void display(int a);

};

#endif // SIMPLEPENDULUM_H

simplependulum.cpp

#include "simplependulum.h"
#include "ui_simplependulum.h"
#include <QtGui>
#include <QPalette>
//#include <QThread>
//#include "multithread.h"
#include <QDebug>
#include<QTimer>
#include<math.h>

static float time_period=0;
static int DEFAULT_X_OFFSET= 500;
static int DEFAULT_Y_OFFSET= 60;
static int DEFAULT_X_PENDULUM_OFFSET= 40;
static int DEFAULT_Y_PENDULUM_OFFSET= 55;
static int DEFAULT_X_INITIAL_PENDULUM_OFFSET= 480;
static int DEFAULT_Y_INITIAL_PENDULUM_OFFSET= 234;
//const int DEFAULT_NO_ROWS =3;
//const int DEFAULT_PENDULUM_NO_ROWS=0;
//const int DEFAULT_NO_COLS=  3;
//const int DEFAULT_WIDTH  =  60;
//const int DEFAULT_HEIGHT =  60;
const float pi =3.14;

SimplePendulum::SimplePendulum(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::SimplePendulum)
{
    ui->setupUi(this);
    //Initialize();

//    thread = new QThread();
//    multithread = new MultiThread();
//
//    multithread->moveToThread(thread);
//    connect(multithread, SIGNAL(valueChanged(QString)), ui->labelCount, SLOT(setText(QString)));
//    connect(multithread, SIGNAL(multithreadRequested()), thread, SLOT(start()));
//    connect(thread, SIGNAL(started()), multithread, SLOT(doMultiThread()));
//    connect(multithread, SIGNAL(finished()), thread, SLOT(quit()), Qt::DirectConnection);
//    connect(multithread,SIGNAL(value(int)),SLOT(display(int)));


}

SimplePendulum::~SimplePendulum()
{
//    multithread->abort();
//    thread->wait();
//    qDebug()<<this->QObject::thread()->currentThreadId();
//    delete thread;
//    delete multithread;
//    delete ui;
}

void SimplePendulum::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
void SimplePendulum::paintEvent(QPaintEvent *pEvent)
{
    int X=DEFAULT_X_OFFSET;
    int Y=DEFAULT_Y_OFFSET;

    QWidget::paintEvent(pEvent);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::red);
    painter.setBrush(QBrush(Qt::green));

    X=DEFAULT_X_OFFSET;
    Y=DEFAULT_Y_OFFSET;
    int XE=DEFAULT_X_PENDULUM_OFFSET;
    int YE=DEFAULT_Y_PENDULUM_OFFSET;
    int XI=DEFAULT_X_INITIAL_PENDULUM_OFFSET;
    int YI=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;

    painter.drawLine(490,60,510,60);
    painter.drawLine(500,60,X,Y+175);
    painter.drawEllipse(XI,YI,XE,YE);



}

void SimplePendulum::Initialize()
{
//     m_NoOfRows=DEFAULT_NO_ROWS;
//     m_NoOfCols=DEFAULT_NO_COLS;
//     m_width=DEFAULT_WIDTH;
//     m_Height=DEFAULT_HEIGHT;
//     m_XOffset=DEFAULT_X_OFFSET;
//     m_YOffset=DEFAULT_Y_OFFSET;
//     m_NoOfPendulumRows=DEFAULT_PENDULUM_NO_ROWS;

}

void SimplePendulum::on_actionStart_activated()
{
    display1(DEFAULT_Y_OFFSET);
    //multithread->abort();
    //thread->wait();
    //multithread->requestThread();
    //display();

}

void SimplePendulum::on_actionPause_activated()
{
    //multithread->abort();
    //thread->wait();

}

void SimplePendulum::on_actionResume_activated()
{
    //multithread->abort();
    //multithread->resume();
    //thread->wait();

}
void SimplePendulum::on_pushButton_clicked()
{

    QString Data1= ui->textEdit_length->toPlainText();
    int iLength=atoi(Data1.toAscii());
    Initialdisplay(iLength);
}

void SimplePendulum::Initialdisplay(int strLength)
{
    if(strLength)
    {
        DEFAULT_Y_OFFSET=strLength;
        int d=strLength-60;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET+d;
        this->repaint();
    }
    ui->pushButton->close();
}
void SimplePendulum::display(int count)
{

    /*if(t==2)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+10;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
this->repaint();
    }
    //t=t--;
   //display(t);
    //display(t);
            if(t==1)
            {
                DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
                DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
                DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+12;
                DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
                DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
                DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
                this->repaint();
            }

    /*if(count==2)
    {

        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==3)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==4)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==5)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==6)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==7)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==8)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
    else if(count==9)
    {
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+10;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+15;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }*/
}



void SimplePendulum::on_pushButton_Reset_clicked()
{
    DEFAULT_X_OFFSET= 500;
    DEFAULT_Y_OFFSET= 60;
    DEFAULT_X_PENDULUM_OFFSET= 40;
    DEFAULT_Y_PENDULUM_OFFSET= 55;
    DEFAULT_X_INITIAL_PENDULUM_OFFSET= 480;
    DEFAULT_Y_INITIAL_PENDULUM_OFFSET= 234;
    this->repaint();
    ui->pushButton->show();
}

void SimplePendulum::on_actionStart_2_activated()
{
    /*multithread->abort();
    thread->wait();
    multithread->requestThread();*/
    display1(DEFAULT_Y_OFFSET);
}

void SimplePendulum::on_actionPause_2_activated()
{
    abort();
    //wait();

}
void SimplePendulum::display1(int strL)
{

    time_period=2*pi*sqrt(strL/9.8);
    float iPeroid=time_period;
    QString period;
    period.sprintf("%f",iPeroid);
    ui->label_Period->setText(period);
    float Motion=time_period/4;
    float iMotion=Motion;
    QString motion;
    motion.sprintf("%f",iMotion);
    ui->label_Motion->setText(motion);
    for(int i=0;i<Motion;i++)
    {
        QEventLoop loop;
        QTimer::singleShot(300, &loop, SLOT(quit()));
        loop.exec();
        DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+5;
        DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET-2;
        DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+5;
        DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET-2;
        DEFAULT_X_PENDULUM_OFFSET=DEFAULT_X_PENDULUM_OFFSET;
        DEFAULT_Y_PENDULUM_OFFSET=DEFAULT_Y_PENDULUM_OFFSET;
        this->repaint();
    }
   for(int i=0;i<Motion;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET+2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET+2;
       this->repaint();

    }
   for(int i=0;i<Motion;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET-2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET-2;
       this->repaint();

    }
   for(int i=0;i<Motion;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET+2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET+2;
       this->repaint();

    }
   for(int i=0;i<Motion-1;i++)
   {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET-2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET-2;
       this->repaint();
   }
   for(int i=0;i<Motion-1;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET+2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET+2;
       this->repaint();

    }
   for(int i=0;i<Motion-1;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET-5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET-2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET-5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET-2;
       this->repaint();

    }
   for(int i=0;i<Motion-1;i++)
    {
       QEventLoop loop;
       QTimer::singleShot(300, &loop, SLOT(quit()));
       loop.exec();
       DEFAULT_X_OFFSET=DEFAULT_X_OFFSET+5;
       DEFAULT_Y_OFFSET=DEFAULT_Y_OFFSET+2;
       DEFAULT_X_INITIAL_PENDULUM_OFFSET=DEFAULT_X_INITIAL_PENDULUM_OFFSET+5;
       DEFAULT_Y_INITIAL_PENDULUM_OFFSET=DEFAULT_Y_INITIAL_PENDULUM_OFFSET+2;
       this->repaint();

    }

}
void SimplePendulum::abort()
{
    QTime dieTime= QTime::currentTime().addSecs(5);
    while( QTime::currentTime() < dieTime )
    QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}

main.cpp

#include <QtGui/QApplication>
#include "simplependulum.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SimplePendulum w;
    w.show();
    return a.exec();
}






Download

   
Messages
Posted:
Post Your Comments
Name (Max 50 Chars)
Comments

TekTipsDownload
GateExam
Academic Projects
TekTipsExperts



 
Site optimized for IE7, 1280 X 768 and above. Copyright © 2010 - 2018 KTS InfoTech
Site Developed Using KTS WebCloud