PDA

View Full Version : Transfer variable from qmainwindow to qwidget



franzib
12th April 2016, 10:55
Hey :)

I have the following problem:
I have a qmainwindow that has only one qwidget. I would like to transfer some variables from the qmainwindow class, which is called struc_window in my implementation into the qwidget class, which is called struc_widget. The variable nodes can easily be loaded into the constructor of struc_window. But then I am not able to get them into struc_widget. I tried it by custom signals and slots or with qobject_cast... I am sitting for days now :(
Some guys told me to solve this problem with standard pointers but it didn't work. I think the problem should be solved with methods related to qobject (as signal and slots etc.)
What I now try to do is to define a pointer to the parent class struc_window: file: struc_widget.cpp, line 19. Unfortunately, it is a Zero Pointer, am I missing something here?
Perhaps you could take a look at my code, perhaps you could give me some advices...




////////////////////////////////// struc_window.h ////////////////////////////////////
#ifndef STRUC_WINDOW_H
#define STRUC_WINDOW_H

#include <QMainWindow>
#include <iostream>
#include "struc_widget.h"
# include "../../c++_fem/Eigen/Eigen/Dense"
using namespace Eigen;
using namespace std;

namespace Ui {
class struc_window;
}

class struc_window : public QMainWindow
{
Q_OBJECT

public:
explicit struc_window(MatrixXd matrix, QWidget *parent = 0);
~struc_window();

MatrixXd nodes;
//MatrixXd elements;
//MatrixXd elements_info;
//MatrixXd bearing_info;
//void set_nodes();
//int a;


signals:
//void mysignal();


private:
Ui::struc_window *ui;

};


#endif // STRUC_WINDOW_H




////////////////////////////////// struc_window.cpp ////////////////////////////////////
#include "struc_window.h"
#include "ui_struc_window.h"
#include "struc_widget.h"
#include <iostream>
using namespace std;

struc_window::struc_window(MatrixXd matrix, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::struc_window)
{
ui->setupUi(this);
nodes = matrix;
//struc_widget *p = new struc_widget;
//connect(this,SIGNAL(mysignal()),p,SLOT(getsignal() ));

}

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




////////////////////////////////// struc_widget.h ////////////////////////////////////
#ifndef STRUC_WIDGET_H
#define STRUC_WIDGET_H

#include <QOpenGLWidget>
#include "struc_window.h"

#include "../../c++_fem/Eigen/Eigen/Dense"
using namespace Eigen;

class struc_widget : public QOpenGLWidget
{
Q_OBJECT
public:
explicit struc_widget(QWidget *parent = 0);



protected:
void initializeGL();
void paintGL();
void resizeGL(int width, int height);

void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);

signals:

public slots:
//void getsignal();

private:
QPoint lastPos;

int xrot,yrot,zrot;
int h;
int b;
double norm_angle_x;
double norm_angle_y;
double norm_angle_z;
void setXRotation(int angle);
void setYRotation(int angle);
void setZRotation(int angle);
void normalize_angle_x(int angle);
void normalize_angle_y(int angle);
void normalize_angle_z(int angle);

void draw_structure();


MatrixXd node_matrix;

};

#endif // STRUC_WIDGET_H



////////////////////////////////// struc_widget.cpp ////////////////////////////////////
#include "struc_widget.h"
#include <QOpenGLWidget>
#include <QtOpenGL>
#include <QtWidgets>
#include <iostream>
using namespace std;

#include "struc_window.h"


struc_widget::struc_widget(QWidget *parent) : QOpenGLWidget(parent)
{
xrot = 0;
yrot = 0;
zrot = 0;
norm_angle_x = 0;
norm_angle_y = 0;
norm_angle_z = 0;
struc_window *struc_window_ptr = qobject_cast<struc_window*>(this->parent()); !!!!!!!!!!!!!!!!!!!!!!!!!!!! this is a zero pointer??????????????????
cout << struc_window_ptr << endl;
//struc_window_ptr->set_nodes();
//struc_window_ptr->set_nodes();


}

void struc_widget::initializeGL()
{
glClearColor(0.5,0.5,0.5,0.4);
}

void struc_widget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glLineWidth(2.5);
normalize_angle_x(xrot);
normalize_angle_y(yrot);
normalize_angle_z(zrot);
glRotatef(norm_angle_x,1,0,0);
glRotatef(norm_angle_y,0,1,0);
glRotatef(norm_angle_z,0,0,1);

glBegin(GL_TRIANGLES);
glColor3f(1,0,0);
glVertex3f(-1,-1,0);
glColor3f(0,1,0);
glVertex3f(1,-1,0);
glColor3f(0,0,1);
glVertex3f(0,1,0);
glEnd();
}

void struc_widget::resizeGL(int width, int height)
{
int side = qMin(width, height);
glViewport((width - side) / 2, (height - side) / 2, side, side);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
#ifdef QT_OPENGL_ES_1
glOrthof(-2, +2, -2, +2,-10, 10);
#else
glOrtho(-2, +2, -2, +2, -10, 10);
#endif
glMatrixMode(GL_MODELVIEW);
h = height;
b = width;
}


void struc_widget::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}

void struc_widget::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->x() - lastPos.x();
int dy = event->y() - lastPos.y();

if (event->buttons() & Qt::LeftButton)
{
setXRotation(xrot + dy);
}
else if (event->buttons() & Qt::RightButton)
{
setYRotation(yrot + dx);
}
else if (event->buttons() & Qt::MiddleButton)
{
setZRotation(zrot + dx);
}

lastPos = event->pos();
}


// x-rotation
void struc_widget::setXRotation(int angle)
{
if (angle != xrot) {
xrot = angle;
update();
}
}

// y-rotation
void struc_widget::setYRotation(int angle)
{
if (angle != yrot) {
yrot = angle;
update();
}
}

// z-rotation
void struc_widget::setZRotation(int angle)
{
if (angle != zrot) {
zrot = angle;
update();
}
}


// normalize angles
void struc_widget::normalize_angle_x(int angle)
{
norm_angle_x = 180.0 / h * angle;
}
void struc_widget::normalize_angle_y(int angle)
{
norm_angle_y = 180.0 / b * angle;
}
void struc_widget::normalize_angle_z(int angle)
{
norm_angle_z = 180.0 / b * angle;
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////// structural data /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

void struc_widget::draw_structure()
{

}


///////////////////////////////////////////////////////
/// slot function
///////////////////////////////////////////////////////
//void struc_widget::getsignal(){

/////////////////////////////////////////////////////////// END OF THE CODE
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////

I already tried to solve this problem by signal - slots also and I think I had a valid connection, but how to transfer the variable nodes then????????

anda_skoa
12th April 2016, 11:37
What do you mean with "transfer"?

If you don't want the data in your main window, just have it in the widget.

If you mean passing data to the widget, then this is just a normal C++ method, a setter.

Or do you change the data in the main window at some point into the operation and need to have the data in the widget updated?
Does the main window need the data itself?

Cheers,
_

weiweiqiao
12th April 2016, 11:47
In you declaration, you want to send you node variable from struc_window to struc_widget, i thought signal/slot is a good choice. however, i did not find variable in your connect metod(maybe you want to connection by this statement //connect(this,SIGNAL(mysignal()),p,SLOT(getsignal() ));); you did not active mysignal in your struc_window class. i thought you should add some code in you files.
step1. You should add widget in your struc_window to emit you signal.
step2. Changing your code to send node from window to widget.

franzib
12th April 2016, 14:13
Hey guys, thank you for responding! :)

@anda_skoa:
I know how to load easily the variable input.nodes from the main function into the object of class struc_window, actually I did that in the constructor. The variable nodes is an array and has drawing information, which I need in the class struc_widget, where everything should be drawn then. This is what I am trying by the pointer in the constructor of struc_widget.
Yes, it has only to be passed once, so I will now try to realize this also by a setter.


@ weiweiqiao:
I will show you the code lines of the running sender slot version in a minute. But I have to admit I really don't know how to implement this in a signal so that the variable nodes is transfered, as that this signal/slot stuff seems always have to do something with pushbutton methods and not custom...

Cheers

anda_skoa
12th April 2016, 14:31
I know how to load easily the variable input.nodes from the main function into the object of class struc_window, actually I did that in the constructor. The variable nodes is an array and has drawing information, which I need in the class struc_widget, where everything should be drawn then. This is what I am trying by the pointer in the constructor of struc_widget.
Yes, it has only to be passed once, so I will now try to realize this also by a setter.

I see.
Then either pass it via a setter or just make the instance in struct_widget accessible via a getter to a reference or pointer.

Cheers,
_

franzib
12th April 2016, 14:39
@weiweiqiao:
in the struc_window.h (qmainwindow) I define a dummy variable (which should be sent) and the signal:

public:
int a;
signals:
void mysignal(int);

in the struc_window.cpp file in the constructor of struc_window I initialize my variable a and define the pointer to struc_widget and the connecter:

a = 1;
struc_widget *p = new struc_widget;
connect(this,SIGNAL(mysignal(int)),p,SLOT(getsigna l(int)));

in the struc_widget.h file i define the slot:

public slots:
void getsignal(int);

and in the struc_widget.cpp file the implementation of the slot

void struc_widget::getsignal(int){}

This seems to compile without error!
My question is: How can I link this procedure now with the dummy variable int a so that it is sent to struc_widget and I could use it later???

Cheers

weiweiqiao
12th April 2016, 14:44
this is a sample for passing data from one dialog to dialog01.
In dialog: one qpushbutton, one qlienedit, in dialog01: qlineedit;

dialog.h



#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

class Dialog01;

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
Q_OBJECT

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

public slots:
void sendText();

signals:
void signalText(QString text);

private:
Ui::Dialog *ui;

Dialog01* pDialog;
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"

#include "dialog01.h"

Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog),
pDialog(new Dialog01(this))
{
ui->setupUi(this);

connect(ui->pushButton, &QPushButton::clicked,
this, &Dialog::sendText);
connect(this, &Dialog::signalText,
pDialog, &Dialog01::recvText);
}

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

void Dialog::sendText()
{
emit signalText(ui->lineEdit->text());

pDialog->setVisible(true);
}


dialog01.h

#ifndef DIALOG01_H
#define DIALOG01_H

#include <QDialog>

namespace Ui {
class Dialog01;
}

class Dialog01 : public QDialog
{
Q_OBJECT

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

public slots:
void recvText(QString text);

private:
Ui::Dialog01 *ui;
};

#endif // DIALOG01_H


dialog01.cpp

#include "ui_dialog01.h"

#include "dialog01.h"

Dialog01::Dialog01(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog01)
{
ui->setupUi(this);
}

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

void Dialog01::recvText(QString text)
{
ui->lineEdit->setText(text);
}


main.cpp

#include <QApplication>

#include "maindialog.h"

#include "dialog.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//MainDialog w;
//w.show();

Dialog d;
d.show();

return a.exec();
}

franzib
12th April 2016, 15:10
Ah I see, I have to implement two connections. One signal in each class and one slot in each class and the variable is emitted in the slot functions, right? ;)

weiweiqiao
12th April 2016, 16:11
yeah, pushbutton's click have no param, so you should send a slot with no param, however, you could emit signal with param which you want in slot method.

anda_skoa
12th April 2016, 23:29
Ah I see, I have to implement two connections. One signal in each class and one slot in each class and the variable is emitted in the slot functions, right? ;)
No.
One signal at the source and one slot at the receiver is enough.

And you don't need signal/slots at all if all you want is to provide initial data to the other object.

The example is a demonstration on how to use signal/slots but in a real project just useless code complexity.

Cheers,
_