-1

I am a newbie in QT and working with its openGL in the Ubuntu Platform

I have created a template as in :

enter image description here

My objective :

On clicking of the "Compute" button, two things are supposed to happen :

  1. A text will be printed in the text box
  2. A line will be drawn on expOutput, which is an object of Experimental, inherited from QGLWidget.

I am creating two signal slots. The codes of the program are given below :

nearestneighbour.h

#ifndef NEARESTNEIGHBOUR_H
#define NEARESTNEIGHBOUR_H

#include <QWidget>
#include <QGLWidget>
#include "experimental.h"


namespace Ui {
class NearestNeighbour;
}

class NearestNeighbour : public QWidget
{
    Q_OBJECT

public:
    explicit NearestNeighbour(QWidget *parent = 0);
    ~NearestNeighbour();


signals:
    void clicked();

private slots:
    void on_Compute_clicked();

private:
    Ui::NearestNeighbour *ui;

};

#endif // NEARESTNEIGHBOUR_H

nearestneighbour.cpp

#include "nearestneighbour.h"
#include "ui_nearestneighbour.h"

NearestNeighbour::NearestNeighbour(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::NearestNeighbour)
{
    //expt = new Experimental(this);
    ui->setupUi(this);
    QObject::connect(ui->Compute, &QPushButton::clicked, ui->expOutput,&Experimental::draw);
    QObject::connect(ui->Compute, &QPushButton::clicked, this,&NearestNeighbour::on_Compute_clicked);
}

NearestNeighbour::~NearestNeighbour()
{
    delete ui;
}


void NearestNeighbour::on_Compute_clicked()
{
    ui->textEdit->setText("Hello World !!");
}

experimental.h

#ifndef EXPERIMENTAL_H
#define EXPERIMENTAL_H

#include <QWidget>
#include <QGLWidget>
#include <iostream>
#include "nearestneighbour.h"
// #include "ui_nearestneighbour.h"

class Experimental : public QGLWidget
{
    Q_OBJECT
public:
    explicit Experimental(QWidget *parent=NULL);


public slots:
    void draw(void);

protected:
    void initializeGL();
    void paintGL();
};

#endif // EXPERIMENTAL_H

experimental.cpp

    #include "experimental.h"

Experimental::Experimental(QWidget *parent): QGLWidget(QGLFormat(QGL::SampleBuffers), parent){}

void Experimental::initializeGL(){
    std::cout<<"In initializegl  !! ";
    qglClearColor(Qt::white);
    glViewport(0,0,600,300);
    glMatrixMode(GL_MODELVIEW);
    glOrtho(0,300,0,600,0,0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Experimental::paintGL(){
    std::cout<<"In paintgl  !! ";
}

void Experimental::draw(void){
    std::cout<<"In draw !!";
    glLoadIdentity();
    qglColor(Qt::blue);
    glBegin(GL_LINE);
        glVertex2i(100,100);
        glVertex2i(200,200);
    glEnd();
    updateGL();
}

Problem :

Thanks to some great suggestions, I was able to remove the errors and the system compiled fine.

The output of the first screen is coming as

enter image description here

I am clicking on the "Compute" button, and the line should be drawn on the openGl widget. However, there are no outputs but after exiting the GUI mode, one can note that there are some relevant messages, which indicate that the functions have been visited.

enter image description here

Can somebody help me in solving the problem?

Chintu
  • 9
  • 2
  • Why is experimental.h including ui_nearestneighbour.h in the first place? – Botje Oct 26 '20 at 07:14
  • Thank you !! removal of the ui_nearestneighbour.h removed the error. But however, the QObject::connect(ui->Compute, SIGNAL(clicked()), ui->expOutput,SLOT(draw())); in nearestneighbour.cpp is still not working !! – Chintu Oct 27 '20 at 05:59
  • Don't use qt4 style signal-slot connections, if that does not reveal anything you need to show more. – Botje Oct 27 '20 at 08:25
  • @Botje : I have updated to the qt5 signal slot method : QObject::connect(ui->Compute, &QPushButton::clicked, ui->expOutput,&Experimental::draw); QObject::connect(ui->Compute, &QPushButton::clicked, this,&NearestNeighbour::on_Compute_clicked); However, there is no display in my opengl widget – Chintu Oct 29 '20 at 07:57
  • The codes have been updated to show that no output is being seen – Chintu Oct 29 '20 at 09:24
  • That is still not the full code: where do you set up your glviewport? Your code seems to assume (200,200) is a valid coordinate. Also, did you see the notice that qglwidget is deprecated and that you should uw qopenglwidget instead? – Botje Oct 29 '20 at 10:09
  • @Botje : The qglWidget has been created using the QT Creator. The width=600 and height=300. The Experimental class is inherited from QGLWidget and QWidget. This QT Creator work environment can be seen from the first figure, where expOutput is the openGL Widget. – Chintu Oct 29 '20 at 13:23
  • Okay, let me try again: where is your call to `glViewport` to set up the OpenGL viewport and where is your call to `glOrtho` to set up your OpenGL projection matrix? The default projection matrix does not show anything drawn at z=0 like the 2d draw calls do. – Botje Oct 29 '20 at 13:51
  • @Botje : The code has been updated, but still no effect. – Chintu Oct 30 '20 at 05:46

1 Answers1

0

If you need to draw outside of paintGL() handler, you have to make context current by a call to makeCurrent() and Qt really doesn't take kindly to attempts to draw outside of paint event plus you would have an issue with order of output (a "painter" problem)

On Qt5+ you should not to use in new programs the old QGLWidget, which relies on fixed pipeline and left for compatibility with legacy code, QOpenGLWidget is your friend. There is a following example in Assistant:

  class MyGLWidget : public QOpenGLWidget
  {
  public:
      MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }

  protected:
      void initializeGL()
      {
          // Set up the rendering context, load shaders and other resources, etc.:
          QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
          f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
          ...
      }

      void resizeGL(int w, int h)
      {
          // Update projection matrix and other size related settings:
          m_projection.setToIdentity();
          m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);
          ...
      }

      void paintGL()
      {
          // Draw the scene:
          QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
          f->glClear(GL_COLOR_BUFFER_BIT);
          ...
      }

  };

QGlWidget you're using got following virtual methods:

virtual void    glDraw ()
virtual void    glInit ()
virtual void    initializeGL ()
virtual void    initializeOverlayGL ()
virtual void    paintGL ()
virtual void    paintOverlayGL ()
virtual void    resizeGL ( int width, int height )
virtual void    resizeOverlayGL ( int width, int height )

You almost never need to override the first two and usually have to override others. glDraw calls glPaintGL after calling makeCurrent

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42