I set a quick example, which I hope will help you understand the mechanisms you need to use to complete your task.
It consists of a Listener class that listens for data and sends it to Widget for drawing. In my example, I set it up so that data is randomly generated and sent at regular intervals using a timer, but in your case it will be the data of your serial port.
Since I guess what you want to do is plot, you cannot use paintEvent to draw individual points, because every time it displays only one point, and the point data does not accumulate, you need to draw a pixmap that you just show in paintEvent .
Here are the Widget and Listener classes:
class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = 0) : QWidget(parent) { resize(200, 200); p = new QPixmap(200, 200); } protected: void paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(0, 0, 200, 200, *p); } public slots: void receiveData(int x, int y) { QPainter painter(p); painter.setBrush(Qt::black); QPoint point(x, y); painter.drawPoint(point); data.append(point); repaint(); } private: QPixmap *p; QVector<QPoint> data; }; class Listener : public QObject { Q_OBJECT public: Listener(QObject *p = 0) : QObject(p) { QTimer * t = new QTimer(this); t->setInterval(200); connect(t, SIGNAL(timeout()), this, SLOT(sendData())); t->start(); } signals: void dataAvaiable(int, int); public slots: void sendData() { emit dataAvaiable(qrand() % 200, qrand() % 200); } };
... and main:
int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; Listener l; QObject::connect(&l, SIGNAL(dataAvaiable(int,int)), &w, SLOT(receiveData(int,int))); w.show(); return a.exec(); }
So, it happens that random data will be generated every 200 ms, sent to the Widget, where it is added to the pixmap, and the Widget updated to show a new record.
EDIT: given how small the dot (pixel) is, you can draw small circles. You can also colorize a point based on its data values ββso that you can get a gradient, for example, low values ββcan be green, but the higher it can get yellow and finally red ...
You may also want to add the received data to the QVector<QPoint> , if you need it later, you can do this in the receiveData slot.
Another thing worth mentioning is that in the example everything is in the range 0-200, data, the graph window is very convenient. This is actually not the case, so you will need to match the data with the size of the graph, which may vary depending on the size of the widget.
Here is a pattern that I usually use to normalize values ββin a certain range. You can simplify it a bit depending on your requirements.
template <typename Source, typename Target> Target normalize(Source s, Source max, Source min, Target floor, Target ceiling) { return ((ceiling - floor) * (s - min) / (max - min) + floor); }
Edit2: added data vector to store all received points in numerical form.