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();
}