PDA

View Full Version : Newbie problem with passing objects to functions



ts66
6th May 2011, 15:56
Hi all,

I just started learning Qt and was working myself through a few tutorials. I have a basic knowledge of c++, but not too much either.

I've written a small programm. In this program I have a class with a QTextEdit object. This class has a member function which I want to add some text to the QTextEdit object. But I seem to be unable to get it working. I guess the problem lies where I call the particular function, but to me this looks correct.

Here is the complete code, the problematic line (line 15) is put as comment ("There is a problem"):

main.cpp:

#include "MyWidget.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QWidget>
#include <QTextEdit>


// Main function
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QApplication>
#include <QVBoxLayout>
#include <QWidget>
#include <QTextEdit>


class MyWidget : public QWidget
{
Q_OBJECT

public:
MyWidget(QWidget *parent = 0);
~MyWidget();
void addtexttofield(QTextEdit*);
};

#endif

MyWidget.cpp


#include "MyWidget.h"

// MyWidget class destructor
MyWidget::~MyWidget()
{}

// MyWidget class constructor
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{

QTextEdit *textfield = new QTextEdit();

// There is a problem
// addtexttofield(textfield);

// Layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textfield);
setLayout(layout);
}

// A function to modify QTextEdit content
void addtexttofield(QTextEdit *zieltextfeld)
{
zieltextfeld -> setText("This is something new");
}

Thanx in advance.

Tl;dr: How do I call function addtexttofield(QTextEdit*)?

meazza
6th May 2011, 16:01
void MyWidget::addtexttofield(QTextEdit *zieltextfeld)
{
zieltextfeld -> setText("This is something new");
}

Try this. Added MyWidget:: before the function name because that is where it is declared

Zlatomir
6th May 2011, 16:03
The problem is that you declare void addtexttofield(QTextEdit*) in MyWidget.h:

class MyWidget : public QWidget
{
Q_OBJECT

public:
MyWidget(QWidget *parent = 0);
~MyWidget();
void addtexttofield(QTextEdit*); //as a member function
};
And define a (separate free function) in MyWidget.cpp:


//...
void addtexttofield(QTextEdit *zieltextfeld) //this line should be void MyWidget::addtexttowidget(QTextEdit *zieltextfeld)
{
zieltextfeld -> setText("This is something new");
}

LE: my answer was little late.... ::o
And you can use the QTextEdit pointer as a member to your class, so that you don't even have to pass the pointer as parameter, you can just use the original member pointer in the void MyWidget::addtexttowidget()

ts66
6th May 2011, 16:15
Now it works. Thanks again.

ts66
6th May 2011, 23:01
Hey, it's me again.



And you can use the QTextEdit pointer as a member to your class, so that you don't even have to pass the pointer as parameter, you can just use the original member pointer in the void MyWidget::addtexttowidget()

I tried to do this, but I am facing new problems. Here is what I have done: I declared textfield as a public member of the MyWidget class (and changed theaddtexttofield declaration):

MyWidget.h


#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QApplication>
#include <QVBoxLayout>
#include <QWidget>
#include <QTextEdit>


class MyWidget : public QWidget
{
Q_OBJECT

public:
MyWidget(QWidget *parent = 0);
~MyWidget();
void addtexttofield();
QTextEdit textfield;
};

#endif

MyWidget.cpp now looks like this:




#include "MyWidget.h"

// MyWidget class destructor
MyWidget::~MyWidget()
{}

// MyWidget class constructor
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{

QTextEdit *textfield = new QTextEdit();

// There is still a problem
// addtexttofield();

// Layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textfield);
setLayout(layout);
}

// A function to modify QTextEdit content
void addtexttofield()
{
textfield.setText("This is something new");
}


I get no compiler errors, and I know addtexttofield is called, as I tested this with a qDebug message. But it doesn't change the content of the the QTextEdit object textfield.

What am I doing wrong?
Thanks in advance again.

Zlatomir
6th May 2011, 23:55
In the code you show us now, you have two textfield one pointer to QTextEdit (declared in the constructor of MyWidget) and one QTextEdit object (member in the MyWidget class) and void addtexttofield() is again a free function, i assume you just edited the previous posted code (that is not the same as the one you have in your project) so post the actual code - else we can't know what is wrong.

ts66
7th May 2011, 00:28
I am sorry.
I corrected the function definition in my project, it is now

void MyWidget::addtexttofield()
, but forgot to update the code I posted here.

The rest is as I posted it here.

The two textfield pointers looked curious to me too, but the code didn't compile when I left out the one from the constructor. I could try this again tomorrow, but I can't access my work machine today.

Zlatomir
7th May 2011, 01:01
Then that is the problem, you create another object (that you add to the layout) and basically show on screen - the one behind the pointer and a second one - the member gets the new text - but this one is never showed.

To fix it you need the pointer as a member in your class declaration:


class MyWidget : public QWidget
{
Q_OBJECT

public:
MyWidget(QWidget *parent = 0);
~MyWidget();
void addtexttofield();
QTextEdit *textfield; //the pointer is a member
};

And then use it as in your previous code that worked:


MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{

QTextEdit *textfield = new QTextEdit(); //initialize the pointer

// There is still a problem
addtexttofield(); //call the function

// Layout
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(textfield); //add it to the layout
setLayout(layout);
}

// A function to modify QTextEdit content
void MyWidget::addtexttofield()
{
textfield->setText("This is something new"); //use the arrow operator -> //because you only have the pointer
}

ts66
9th May 2011, 10:21
Thanks again for your help. Although I worked through a number c++ of tutorials and had no problems with the exercises, there is obviously still a lot I don't understand. Well, I guess this will change when I do more programming. :-)

When I tried the code example you gave, the programm crashed with a segmentation fault when calling the function addtextofield(). So I decided to work a bit more on my c++ basics before coming back to this problem.

The problem is the initialization of textfield in MyWidget.cpp. It works when the line looks like this:

textfield = new QTextEdit();
instead of

QTextEdit *textfield = new QTextEdit();
(which probably simply creates a new instance, but leaves the one declared in the header file uninitialised.)

stampede
9th May 2011, 10:33
(which probably simply creates a new instance, but leaves the one declared in the header file uninitialised.)
Exactly, that's why it's good habit to use this keyword to reference data members:


this->textfield = new QTextEdit();

Some programmers use various naming conventions for data members, like:


// some class...
class Class{
...
protected:
int _value; // or:
QString m_text; // m stands for 'member', or even:
float data_;
...

This way you can distinguish between data members and local variables even without the this keyword:


void Class::setValues( int value, QString text ){
_value = value;
m_text = text;
}

Zlatomir
9th May 2011, 11:22
@ts66 this is my mistake (i forgot to delete the type there), so as you figure in out the correct line is supposed to be:

textfield = new QTextEdit(); //textfield is declared as a class member in the header file, here we just use it - don't re-declare it