There is a server and a client program. Server should be started first and when the client gets connected to server, server sends array(floating values) of data through socket
The first four bytes of the data which is send through socket contains the total number of floating values(size of array).
here is the server program
//ss.h server program
#ifndef SS_H_
#define SS_H_
#include <QtGui>
#include <QtNetwork>
{
Q_OBJECT
public:
SS();
private slots:
void send_data();
private:
float *val_var;
long val_var_size;
};
#endif /*SS_H_*/
#ifndef SS_H_
#define SS_H_
#include <QtGui>
#include <QtNetwork>
class SS:public QWidget
{
Q_OBJECT
public:
SS();
private slots:
void send_data();
private:
float *val_var;
long val_var_size;
QTcpServer *server;
};
#endif /*SS_H_*/
To copy to clipboard, switch view to plain text mode
//ss.cpp
#include "ss.h"
#include <QtGui>
SS::SS()
{
val_var_size=180000;
val_var =new float[val_var_size];
for (long i=0; i<val_var_size; i++)
{
*(val_var+i)=i;
qDebug()<<*(val_var+i);
}
//send the data through socket
{
qDebug()<<"unable to listen to port";
exit(1);
}
else
qDebug()<<"Server is running ,Start the client";
connect(server, SIGNAL(newConnection()), this, SLOT(send_data()));
}
void SS::send_data()
{
out << (quint32)0;
for (long i=0; i<val_var_size; i++)
out<<*(val_var+i);
//write the size of array in the first 4 bytes of data.
out.device()->seek(0);
out << (quint32)(val_var_size);
QTcpSocket *socket
= server
->nextPendingConnection
();
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
socket->write(block);
socket->disconnectFromHost();
qDebug()<<"ALL data has been send to socket..";
}
int main(int argc, char *argv[])
{
SS s;
return app.exec();
}
#include "ss.h"
#include <QtGui>
SS::SS()
{
val_var_size=180000;
val_var =new float[val_var_size];
for (long i=0; i<val_var_size; i++)
{
*(val_var+i)=i;
qDebug()<<*(val_var+i);
}
//send the data through socket
server =new QTcpServer();
if (!server->listen(QHostAddress::Any, 9999))
{
qDebug()<<"unable to listen to port";
exit(1);
}
else
qDebug()<<"Server is running ,Start the client";
connect(server, SIGNAL(newConnection()), this, SLOT(send_data()));
}
void SS::send_data()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << (quint32)0;
for (long i=0; i<val_var_size; i++)
out<<*(val_var+i);
//write the size of array in the first 4 bytes of data.
out.device()->seek(0);
out << (quint32)(val_var_size);
QTcpSocket *socket = server->nextPendingConnection();
connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
socket->write(block);
socket->disconnectFromHost();
qDebug()<<"ALL data has been send to socket..";
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
SS s;
return app.exec();
}
To copy to clipboard, switch view to plain text mode
In the client program there is a seperate thread which reads the data from socket and stores in array, where as the main class(ie.class PLOT) reads the data stored in the array and starts to paint on the pixmap based on the array values.
The thread which works on the socket ,first stores the first four bytes(size of the array) in a variable.
The main class(ie.class PLOT) needs this value to decide, the number of polygons a circle should be split in to.And then based on the array values the polygons are painted with different colors.
So main class(ie.class PLOT) has to wait till the thread(th class) stores the first 4 bytes(size of array) .also the events (paint event) should not get blocked(ie.if a widget is created and showed it should get displayed even when the main class(class PLOT) is in wait state)
the waitconditions examples does array access but does not deal with any gui.
//plot.h client program
#ifndef PLOT_H_
#define PLOT_H_
#include <QtGui>
#include <QtNetwork>
{
Q_OBJECT
public:
th();
void run();
float *arr;
quint32 blocksize;
quint32 blocksize_check;
private slots:
void read_socket();
private:
};
{
Q_OBJECT
public:
PLOT();
protected:
private:
th t;
QVector<QPolygonF> pol;
qreal zoomfactor;
};
#endif /*PLOT_H_*/
#ifndef PLOT_H_
#define PLOT_H_
#include <QtGui>
#include <QtNetwork>
class th : public QThread
{
Q_OBJECT
public:
th();
void run();
float *arr;
quint32 blocksize;
quint32 blocksize_check;
private slots:
void read_socket();
private:
QTcpSocket *socket;
};
class PLOT : public QMainWindow
{
Q_OBJECT
public:
PLOT();
protected:
void paintEvent(QPaintEvent *);
void wheelEvent(QWheelEvent * event);
void mouseMoveEvent(QMouseEvent * event);
void mousePressEvent(QMouseEvent *event);
private:
th t;
QVector<QPolygonF> pol;
QPixmap pixmap;
QPixmap pixmap_scaled;
qreal zoomfactor;
QPoint mouse_press;
QPoint offset;
};
#endif /*PLOT_H_*/
To copy to clipboard, switch view to plain text mode
//plot.cpp
#include "plot.h"
#include <QtTest>
#include <math.h>
#include <qwt_color_map.h>
#include <qwt_double_interval.h>
th::th() :
blocksize(0), blocksize_check(0)
{
}
void th::run()
{
socket->connectToHost("127.0.0.1", 9999);
connect(socket, SIGNAL(readyRead()), this, SLOT(read_socket()));
exec();
}
void th::read_socket()
{
qDebug()<<"read_socket";
if (blocksize == 0)
{
if (socket->bytesAvailable() < (int)sizeof(quint32))
return;
in >> blocksize;
qDebug()<<"inside if";
wc.wakeAll();
arr=new float[blocksize];
qDebug()<<" block size "<<blocksize;
}
//fill the array which is accessed by the PLOT class later
while (blocksize_check<blocksize)
{
in>>*(arr+blocksize_check);
blocksize_check++;
}
}
PLOT::PLOT() :
zoomfactor(1)
{
resize(800, 600);
t.start();
offset.setX(0);
offset.setY(0);
int degree=360;
int coloum;
wc.wait(&m); // replacing with QTest::qWait(5000); makes work
coloum=(int)(t.blocksize/360);
qDebug()<<" PLOT "<<t.blocksize<<"coloum "<<coloum;
while (t.blocksize == (qint32)0)
{
qDebug()<<" PLOT inside while "<<t.blocksize;
coloum=(int)(t.blocksize/360);
}
//calculate the polygon points (a circle is split in to (degree*coloum) polygons)
for (int i = 0; i<degree; i++)
{
for (int j=0; j<coloum; j++)
{
points[0].setX(j * cos(i*(3.14/180)));
points[0].setY(j * sin(i*(3.14/180)));
points[1].setX((j +1)* cos(i*(3.14/180)));
points[1].setY((j +1)* sin(i*(3.14/180)));
points[2].setX((j +1)* cos((i+1)*(3.14/180)));
points[2].setY((j +1)* sin((i+1)*(3.14/180)));
points[3].setX((j)* cos((i+1)*(3.14/180)));
points[3].setY((j)* sin((i+1)*(3.14/180)));
QVector<QPointF> vecp;
for (int k=0; k<4; k++)
vecp.append(points[k]);
pol.append(polygon);
}
}
//find min and max value to set the color value
float min=0, max=0;
for (int i=0; i<(int)t.blocksize; i++)
{
if (*(t.arr+i)>max)
max=*(t.arr+i);
if (*(t.arr+i)<min)
min=*(t.arr+i);
qDebug()<<*(t.arr+i)<<" "<<i;
}
pixmap
= QPixmap(coloum
*2, coloum
*2);
pixmap.fill(Qt::transparent);
painter.
setRenderHint(QPainter::Antialiasing,
true);
painter.translate(coloum, coloum);
for (int i = 0; i<degree; i++)
{
for (int j=0; j<coloum; j++)
{
painter.save();
painter.
setBrush(QBrush(colorMap.
color(di,
*(t.
arr +(coloum
*i
+j
)))));
painter.setPen(colorMap.color(di, *(t.arr+(coloum*i+j))));
painter.drawPolygon(pol.at(coloum*i+j));
painter.restore();
}
}
pixmap_scaled=pixmap.scaled(1*pixmap.size());
}
{
painter.save();
painter.drawPixmap(offset, pixmap_scaled);
painter.restore();
}
{
if (event->delta()>0)//if rotated forward delta() gives positive value
zoomfactor=zoomfactor+0.055;
else
zoomfactor=zoomfactor-0.055;
QSize oldsize
= pixmap_scaled.
size();
pixmap_scaled=pixmap.scaled(zoomfactor*pixmap.size());
QSize newsize
= pixmap_scaled.
size();
QSize tempsize
= (oldsize
-newsize
)/2;
offset.setX(offset.x()+tempsize.width());
offset.setY(offset.y()+tempsize.height());
update();
}
{
offset=event->pos()-mouse_press+offset;
mouse_press=event->pos();
update();
}
{
mouse_press=event->pos();
}
#include "plot.h"
#include <QtTest>
#include <math.h>
#include <qwt_color_map.h>
#include <qwt_double_interval.h>
QMutex m;
QWaitCondition wc;
th::th() :
blocksize(0), blocksize_check(0)
{
}
void th::run()
{
socket=new QTcpSocket();
socket->connectToHost("127.0.0.1", 9999);
connect(socket, SIGNAL(readyRead()), this, SLOT(read_socket()));
exec();
}
void th::read_socket()
{
qDebug()<<"read_socket";
QDataStream in(socket);
if (blocksize == 0)
{
if (socket->bytesAvailable() < (int)sizeof(quint32))
return;
in >> blocksize;
qDebug()<<"inside if";
wc.wakeAll();
arr=new float[blocksize];
qDebug()<<" block size "<<blocksize;
}
//fill the array which is accessed by the PLOT class later
while (blocksize_check<blocksize)
{
in>>*(arr+blocksize_check);
blocksize_check++;
}
}
PLOT::PLOT() :
zoomfactor(1)
{
resize(800, 600);
t.start();
offset.setX(0);
offset.setY(0);
int degree=360;
int coloum;
wc.wait(&m); // replacing with QTest::qWait(5000); makes work
coloum=(int)(t.blocksize/360);
qDebug()<<" PLOT "<<t.blocksize<<"coloum "<<coloum;
while (t.blocksize == (qint32)0)
{
qDebug()<<" PLOT inside while "<<t.blocksize;
coloum=(int)(t.blocksize/360);
}
//calculate the polygon points (a circle is split in to (degree*coloum) polygons)
QPointF points[4];
for (int i = 0; i<degree; i++)
{
for (int j=0; j<coloum; j++)
{
points[0].setX(j * cos(i*(3.14/180)));
points[0].setY(j * sin(i*(3.14/180)));
points[1].setX((j +1)* cos(i*(3.14/180)));
points[1].setY((j +1)* sin(i*(3.14/180)));
points[2].setX((j +1)* cos((i+1)*(3.14/180)));
points[2].setY((j +1)* sin((i+1)*(3.14/180)));
points[3].setX((j)* cos((i+1)*(3.14/180)));
points[3].setY((j)* sin((i+1)*(3.14/180)));
QVector<QPointF> vecp;
for (int k=0; k<4; k++)
vecp.append(points[k]);
QPolygonF polygon(vecp);
pol.append(polygon);
}
}
QwtLinearColorMap colorMap(Qt::blue, Qt::red);
//find min and max value to set the color value
float min=0, max=0;
for (int i=0; i<(int)t.blocksize; i++)
{
if (*(t.arr+i)>max)
max=*(t.arr+i);
if (*(t.arr+i)<min)
min=*(t.arr+i);
qDebug()<<*(t.arr+i)<<" "<<i;
}
QwtDoubleInterval di(min, max);
pixmap = QPixmap(coloum*2, coloum*2);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.translate(coloum, coloum);
for (int i = 0; i<degree; i++)
{
for (int j=0; j<coloum; j++)
{
painter.save();
painter.setBrush(QBrush(colorMap.color(di, *(t.arr +(coloum*i+j)))));
painter.setPen(colorMap.color(di, *(t.arr+(coloum*i+j))));
painter.drawPolygon(pol.at(coloum*i+j));
painter.restore();
}
}
pixmap_scaled=pixmap.scaled(1*pixmap.size());
}
void PLOT::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.save();
painter.drawPixmap(offset, pixmap_scaled);
painter.restore();
}
void PLOT::wheelEvent(QWheelEvent * event)
{
if (event->delta()>0)//if rotated forward delta() gives positive value
zoomfactor=zoomfactor+0.055;
else
zoomfactor=zoomfactor-0.055;
QSize oldsize = pixmap_scaled.size();
pixmap_scaled=pixmap.scaled(zoomfactor*pixmap.size());
QSize newsize= pixmap_scaled.size();
QSize tempsize = (oldsize-newsize)/2;
offset.setX(offset.x()+tempsize.width());
offset.setY(offset.y()+tempsize.height());
update();
}
void PLOT::mouseMoveEvent(QMouseEvent * event)
{
offset=event->pos()-mouse_press+offset;
mouse_press=event->pos();
update();
}
void PLOT::mousePressEvent(QMouseEvent *event)
{
mouse_press=event->pos();
}
To copy to clipboard, switch view to plain text mode
//main.cpp
#include <QtGui>
#include "plot.h"
int main(int argc, char *argv[])
{
PLOT p;
p.show();
return a.exec();
}
#include <QtGui>
#include "plot.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PLOT p;
p.show();
return a.exec();
}
To copy to clipboard, switch view to plain text mode
i have attached the same program with this post.
Note:The client program uses qwt-5.0.2 and hence it is required to run the application.
In the server program the values send through socket(array) are read from netcdf files and it requires its own libraries ,That is why i am sending incremental values through the socket.
Bookmarks