[Programming a pushbutton to do a certain task]
-
@jsulm First of all.
Thank you for your reply.The problem is that I need this push button to execute a function that can only be called inside the paintGL() method of the class MainWidget.
The paintGL() method render the object and ensure its rotation using the
void QMatrix4x4::rotate(const QQuaternion &quaternion)
I don't see how I can access to that function and execute it using the push button.
-
@appdev As IU wrote: add a public method to your MainWidget class:
class MainWidget... public: void rotate() { localMatrix.rotate(quaternion); }
And then simply call that method in MainWindow:
void MainWindow::on_pushButton_3_clicked() { ui->mainwidget->rotate(); }
You would need to implement MainWidget as a stand-alone widget and promote it to your ui.
-
@appdev
I can't get into a discussion about OpenGl or matrices or quaternions because I know nothing about any of it :)But consider your line
this->ui->mainwidget->localMatrix.rotate(this->ui->mainwidget->quaternion);
Note how both the method call and the parameter start with
this->ui->mainwidget
. So you can factor what this does away into your definition of yourMainWidget
class.EDIT Oh @jsulm has just shown you :)
-
@jsulm @JonB I tried to do that but there is a problem.
To make that public method work, localMatrix should be a member variable of mainwidget. However I want it to be a local variable of the paintGL() function. Otherwise, a problem will occur when it comes to rendering the object and its coordinate system.
The localMatrix here is my modelview matrix. I used it to render an object ( a cube ) and two coordinate systems that are attached to it.
When I declare localMatrix as a member variable, one of the coordinate system becomes detached from the object. -
@appdev said in [Programming a pushbutton to do a certain task]:
localMatrix should be a member variable of mainwidget
It is already according to your code:
this->ui->mainwidget->localMatrix.rotate(this->ui->mainwidget->quaternion);
So, don't know what the problem is...
-
Yes, according to my code, it is a member variable, I changed it so I can use it in the mainwindow.cpp.
But then, I had some problems when rendering the scene ( as I mentioned one of the coordinate system became detached of the object so something went wrong).
But I don't want it to be a member variable. I want it to be a local so that I can avoid the rendering problem. -
Update:
@jsulm @JonB
I declared a boolean variable in my mainwidget.h:Bool ApplyRotation;
Then each time ApplyRotation is true, the object changes its orientation.
In mainwindow.cpp:
void MainWindow::on_pushButton_3_clicked() { this->ui->mainwidget->ApplyRotation = true; }
In my mainwidget.cpp:
if(ApplyRotation == true) { ApplyRotation=False; EulerAngles.append(quaternion.toEulerAngles()); //rotation order is 213. localMatrix.rotate(quaternion); }
However, when I insert quaternion values in the spin boxes and then click on Apply button, the object changes its orientation and then goes back to its initial orientation. I want it to stay at the new position.
So I removed the line
ApplyRotation=False;
Now after inserting the quaternion values in the spin boxes and then clicking on the apply button, the object changes its orientation.
But, when I change again the values in the spin boxes the object keeps rotating. It means I don't need to click on the button anymore. That's the problem.My goal is to make the object rotate each time I click on the push button.
I don't get why it is not working with the first code I posted. However what I did seems so logical. -
@appdev
I don't see anything in your code where anyone could possibly comment on your behaviour. All we see is setting & testing a boolean variable, how can that tell us/you what your issue is?My goal is to make the object rotate each time I click on the push button.
Then you need to call whatever code from your pushbutton clicked slot. Simply setting a variable there won't even make anything hit the
if(ApplyRotation == true)
elsewhere in your code. -
Okay,
I put that code because I thought that the rest of it isn't necessary to show .
Here is my paintGL() method in the class MainWidget:void MainWidget::paintGL() { //qDebug()<<__func__; // Clear color and depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //================Orbital Frame ==========================================// QMatrix4x4 localMatrix; glMatrixMode(GL_PROJECTION); glLoadMatrixf(projection.constData()); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(localMatrix.constData()); gluLookAt(2.0,2.0,0.0,0.0,0.0,-5.0,0.0,1.0,0.0); glTranslatef(0.0,0.0,-5.0); glRotatef(180.0,0.0,1.0,0.0); glRotatef(-90.0,1.0,0.0,0.0); glScalef(0.4,0.4,0.4); //glMatrixMode(GL_PROJECTION); DrawOrbitalFrame(); program.bind(); texture->bind(); // Calculate model view transformation //qDebug()<<"modelview before transformation"<<matrix; //qDebug()<<"modelview matrix"<<localMatrix; localMatrix.setToIdentity(); localMatrix.lookAt(QVector3D(2.0, 2.0, 0.0), QVector3D(0.0,0.0,-5.0),QVector3D(0.0,1.0,0.0)); localMatrix.translate(0.0, 0.0, -5.0); localMatrix.scale(0.4,0.4,0.4); quaternion = QQuaternion(quat_w, quat_x, quat_y, quat_z); quaternion.normalize(); // Normalizing my quaternion if(ApplyRotation == true) { EulerAngles.append(quaternion.toEulerAngles()); //rotation order is 213. localMatrix.rotate(quaternion); } program.setUniformValue("mvp_matrix", projection * localMatrix); update(); //! [6] //! // Use texture unit 0 which contains cube.png program.setUniformValue("texture", 0); // Draw cube geometry geometries->drawCubeGeometry(&program); texture->release(); program.release(); }
And in my MainWindow class where I programmed the push button:
void MainWindow::on_pushButton_3_clicked() { this->ui->mainwidget->ApplyRotation = true; }
That's what I actually did, I called the variable applyRotation in my my piantGL() method to rotate the object once the user inserts the quaternion value and click on the push button.