How to send a Qline coordinate to a QPainter Widget

I created Qwidget, Form_temp, which draw lines based on the data array created in the parent widget of MainWindow. The problem I am facing is the data that I send from MainWindow to Form_temp through the slot. Send_data is not visible by other functions in Form_temp. (PaintEvent).

I can not calculate the hole in the loop. I added some debugging points to verify that the data is coming in Form_temp.

Here is the code with some explanation. I did this using QTCreator. Please help, I will spend a few days on this and cannot move forward.

Another question: paintEven happens every time a user moves the mouse or another widget updates its presentation (for example, I have a timestamp). I would like to filter out QPaintevens, I just want an update when the data changes. Is there a better way to do this than what I encoded?

Qwidget: header

#ifndef FORM_TEMP_H #define FORM_TEMP_H #include <QWidget> #include <QDebug> namespace Ui { class Form_temp; } class Form_temp : public QWidget { Q_OBJECT public: QPainter *p; void paintEvent(QPaintEvent*); explicit Form_temp(QWidget *parent = 0); ~Form_temp(); void send_data (int *parray, int asize); int array[48]; int size; bool myupdate; private: Ui::Form_temp *ui; }; #endif // FORM_TEMP_H 

Qwidget: core

 #include "form_temp.h" #include "ui_form_temp.h" #include <cstdlib> #include <QPainter> #include <QDebug> Form_temp::Form_temp(QWidget *parent) : QWidget(parent), ui(new Ui::Form_temp) { myupdate = false; ui->setupUi(this); } Form_temp::~Form_temp() { delete ui; } void Form_temp::paintEvent(QPaintEvent*) { qDebug("Paintevent occurs"); if (myupdate) { // Event happen whenever I move the mouse, // I only want an update when data changes. p = new QPainter(this); QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin); p->setPen(pen); p->setRenderHint(QPainter::Antialiasing,true); qDebug()<< "this size" <<size; for (int i= 0; i< size; ++i) { qDebug()<< "array[i" <<i <<"]="<< array[i]; } [...] p->drawLine(x1,y1,x2,y2); [...] } myupdate = false; } void Form_temp::send_data (int *parray, int asize){ size = asize; for (int i= 0; i< asize; ++i) {array[i] = parray[i];} myupdate = true; // make sure the event will update the drawing this->update(); // create a Qpaint Event qDebug()<< size; // print the data so we know we are passing data correctly for (int i= 0; i< asize; ++i) { qDebug()<< "array[i" <<i <<"]="<< array[i]; } } 

MainWindow: title

  #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QtGui> #include "gpio.h" #include "form_temp.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); //QPropertyAnimation *m_ani ; //QPropertyAnimation *m_ani2 ; Form_temp *temp_graph; [...] #endif // MAINWINDOW_H 

MainWindow: core

  MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ // Start UI ui->setupUi(this); temp_graph = new Form_temp; startTimer(1000); // get timer event every sec. } void MainWindow::timerEvent(QTimerEvent *event) { int data[]= {1,2,3}; temp_graph->send_data(data, 3); } [...] 

Thank you for reading. Sebastien.

+1
source share
1 answer

It is very difficult to evaluate the code because it is posted here.

It looks like you created a subclass of QWidget , Form_temp , using Qt Designer, which means that it has extra baggage with a design that it really doesn't need.

When you create your instance of Form_temp , you do not set MainWindow as the parent in the constructor, so I'm not quite sure how your custom widget will draw by itself, since it never gets a show() call. It also never collapsed.

There is no necessary wiring to use the slot and implementation, so it is impossible to determine if this is a problem in this situation.

It should be possible for you to achieve your goal :) I would highly recommend that you look at the Qt Analog Clock Example , as this demonstrates pretty well how to implement your own widget.

You mentioned that you only want your widget to update when data changes, but you don’t understand how the Qt system works. You want your widget to draw itself when you change data, but this is not the only time the widget will draw itself, so you should not try to limit the drawing operation this way.

Put the code in paintEvent() , which will draw the entire widget as you want it to be displayed based on the current data. The frame will execute paintEvent() when the widget first appears, when it is detected after it has previously been closed by another window and in many other situations that you do not control.

Add the usual methods (no need for slots) that will allow you to change the underlying data outside the class and make sure that these methods include the call to update() at the end of them so that they display the structure in which the widget should be repainted.

If your widget is complicated and slow to draw, you can look at the area specified in the event passed to paintEvent() to restrict your drawing code to only the region that needs to be updated.

UPDATE:

Your code is close. I cut it to the ground to demonstrate the basics. You must be able to design it for your needs.

main.cpp

 #include <QApplication> #include "MainWindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); MainWindow mainWindow; mainWindow.show(); return app.exec(); } 

mainwindow.h

 #ifndef _MAINWINDOW_H #define _MAINWINDOW_H #include "Form_temp.h" #include <QWidget> #include <QTimer> class MainWindow : public QWidget { Q_OBJECT public: MainWindow(); virtual ~MainWindow(); private: Form_temp *temp_graph; QTimer m_timer; private slots: void slot_timeout(); }; #endif /* _MAINWINDOW_H */ 

main.cpp

 #include "MainWindow.h" MainWindow::MainWindow(): temp_graph(0), m_timer(this) { temp_graph = new Form_temp(this); connect(&m_timer, SIGNAL(timeout()), this, SLOT(slot_timeout())); m_timer.start(1000); } MainWindow::~MainWindow() { } void MainWindow::slot_timeout() { int y = temp_graph->getY(); y++; if(y > 10) { y = 0; } temp_graph->setY(y); } 

Form_temp.h

 #ifndef _FORM_TEMP_H #define _FORM_TEMP_H #include <QWidget> class Form_temp : public QWidget { Q_OBJECT public: Form_temp(QWidget *parent = 0); virtual ~Form_temp(); void setY(const int newY); int getY(); protected: void paintEvent(QPaintEvent *event); private: int m_y; }; #endif /* _FORM_TEMP_H */ 

Form_temp.cpp

 #include "Form_temp.h" #include <iostream> #include <QPaintEvent> #include <QPainter> #include <QPen> using namespace std; Form_temp::Form_temp(QWidget *parent) : QWidget(parent), m_y(1) { cout << "Form_temp created." << endl; } void Form_temp::setY(const int newY) { m_y = newY; update(); } int Form_temp::getY() { return m_y; } Form_temp::~Form_temp() { cout << "Form_temp destroyed." << endl; } void Form_temp::paintEvent(QPaintEvent *event) { cout << "Form_temp paintEvent." << endl; QPainter p(this); QPen pen(Qt::green, 3, Qt::DashDotLine, Qt::RoundCap, Qt::RoundJoin); p.setPen(pen); p.setRenderHint(QPainter::Antialiasing, true); p.drawLine(0, m_y, width(), m_y); } 
0
source

All Articles