cómo enviar la coordenada Qline a un widget de QPainter

Creé un Qwidget, Form_temp, que dibuja líneas basadas en una matriz de datos creados en el widget principal MainWindow. El problema al que me enfrento es que los datos que envío desde MainWindow a Form_temp a través de la ranura send_data no son vistos por otras funciones en Form_temp. (PaintEvent).

No soy capaz de averiguar el agujero del bucle. Agregué pocos puntos de depuración para validar que los datos llegan a Form_temp.

Aquí está el código con alguna explicación. Hice esto con QTCreator. Por favor, ayúdeme, pasé unos días en esto y no puedo seguir adelante.

Otra pregunta: PaintEven ocurre cada vez que el usuario mueve el mouse u otro widget está actualizando su vista (por ejemplo, tengo una etiqueta que muestra la hora). Me gustaría filtrar los QPaintevens, solo quiero una actualización cuando los datos cambian. ¿Hay una mejor manera de hacer esto que lo que he codificado?

Qwidget: cabecera

#ifndef FORM_TEMP_H #define FORM_TEMP_H #include  #include  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: núcleo

 #include "form_temp.h" #include "ui_form_temp.h" #include  #include  #include  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 <<"]="<drawLine(x1,y1,x2,y2); [...] } myupdate = false; } void Form_temp::send_data (int *parray, int asize){ size = asize; for (int i= 0; iupdate(); // 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: encabezado

  #ifndef MAINWINDOW_H #define MAINWINDOW_H #include  #include  #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 

Ventana principal: núcleo

  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); } [...] 

Gracias por leer. Sebastien.

Es muy difícil evaluar el código como se publica aquí.

Parece que creaste la subclase QWidget , Form_temp , usando Qt Designer, lo que significa que tiene un equipaje adicional en tiempo de diseño que realmente no necesita.

Cuando creas tu instancia de Form_temp , no estás configurando MainWindow como padre en el constructor, así que no estoy muy seguro de cómo se pintaría tu widget personalizado, ya que nunca recibe una llamada para show() . También nunca se destruye.

El cableado requerido para usar una ranura y la implementación tampoco está presente, por lo que no es posible determinar si esa es un área problemática en esta situación.

Sin embargo, debería ser posible que logre su objective 🙂 Le recomiendo encarecidamente que revise el Ejemplo de reloj analógico Qt, ya que esto demuestra bastante bien cómo implementar su propio widget.

Menciona que solo desea que su widget se actualice cuando cambie los datos, pero no entiende cómo funciona el marco Qt. Desea que su widget se pinte solo cuando cambie los datos, pero esta no es la única vez que el widget tendrá que pintarse, por lo que no debe intentar restringir la operación de pintura de esa manera.

Ponga el código en paintEvent() que pintará todo el widget como desee que aparezca en función de los datos actuales. El marco ejecutará paintEvent() cuando aparezca el widget por primera vez, cuando se paintEvent() después de haber sido ocultado previamente por otra ventana y muchas otras situaciones sobre las que no tiene control.

Agregue métodos comunes (sin necesidad de ranuras) que le permitan cambiar los datos subyacentes desde fuera de la clase y asegúrese de que esos métodos incluyan una llamada a update() al final de ellos para que indiquen al marco que el widget debe volver a pintarse. .

Si su widget es complicado y lento para pintar, puede mirar la región especificada en el evento que se pasó a paintEvent() para restringir su código de pintura solo a la región que necesita actualizarse.

ACTUALIZAR:

Tu código está cerca. Lo he recortado a lo esencial para demostrar lo básico. Usted debe ser capaz de elaborar sobre él para sus necesidades.

main.cpp

 #include  #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  #include  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  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  #include  #include  #include  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); }