PDA

View Full Version : QList & QPointer to store object list



maddog_fr
7th August 2009, 12:35
Hello, there. it's me again :o

I have a class HTMLWindow


class HTMLWindow : public QWidget
{
Q_OBJECT
......
}




and I have a class as QApplication that manage thoses windows


class HTMLWindow;

class WidgetManager : public QApplication
{
Q_OBJECT

public:
WindowManager(int &argc, char **argv);
~WindowManager();

void addWindow(void);

QList<QPointer<HTMLWindow> > WindowList;

private:
QSystemTrayIcon *trayIcon;
QMenu *trayIconMenu;
QAction *quitAction;
};



then my problem is in WindowManager::addWindow()


void WidgetManager::addWindow(void){
HTMLWindow *newwindow = new HTMLWindow();
newwindow.setGeometry(QRect(100,100,285,110)); // error1
WindowList->append(newwindow); //error 2
}


Error 1 is : request for member `load' in `newwindow', which is of non-class type `HTMLWindow*'
Error 2 is : base operand of `->' has non-pointer type `QList<QPointer<HTMLWindow> >'

I followed the example browser in Qt\demos\browser

when i call addWindow the newWindow is created but seems i cannot access its method


I dont find where is the problem, are the two error linked ?

thx for your help

maddog_fr
7th August 2009, 12:49
I Managed to solve Error 1 by doing



HTMLWindow(newwindow).setGeometry(QRect(100,100,28 5,110));


seems newwindow is a pointer not an object

A new problem is the window is created 3 times then destroyed 3 times (i put msgbox in constructor/destructor)

maddog_fr
7th August 2009, 12:53
I also replaced


QList<QPointer<HTMLWindow> > WindowList;


by



QList<QPointer<HTMLWindow> > *WindowList;


and now the application end itself with an error code -1073741819

caduel
7th August 2009, 14:21
do you initialize that pointer

QList<QPointer<HTMLWindow> > *WindowList;
in your constructor?

Calling "->append" on an unitialized pointer is a sure way to have "fun" ;-)
(fun of course meaning usually a crashing app)

maddog_fr
7th August 2009, 16:50
do you initialize that pointer

in your constructor?

Calling "->append" on an unitialized pointer is a sure way to have "fun" ;-)
(fun of course meaning usually a crashing app)

No I didnt. But i dont think


QList<QPointer<HTMLWindow> > *WindowList;

is a correct declaration

and i read on another post of this forum that QList dont need to be initialized

spirit
7th August 2009, 16:58
this should work


...
QList<QPointer<HTMLWindow> > WindowList;
WindowList.append(new HTMLWindow(this));
WindowList << new HTMLWindow(this);

WindowList.at(0)->someMethod();
...

maddog_fr
7th August 2009, 18:38
This nearly work


void WindowManager::addHTMLWindow(void){
WindowList.prepend(new HTMLWindow());
HTMLWindow(WindowList.at(0)).setGeometry(QRect(100 ,100,285,110));
}


I cannot put "this" in the constructor of HTMLWindow because Qwidget is expected and "this" is a Qapplication

the HTMLWindow is created and it's method is called but is destroyed at the end of the method ! maybe because i dont give a parent in the constructor ?

caduel
8th August 2009, 08:08
i) QList does not need to be initialized, but QList<...>* is a pointer (to a QList) and all pointer do
ii) QList<QPointer<HTMLWindow> > *WindowList;
is definitely correct. Maybe it is not what you want, but it is correct.
iii)

WindowList.prepend(new HTMLWindow());
HTMLWindow(WindowList.at(0)).setGeometry(QRect(100 ,100,285,110));

creates two HTMLWindows. One with new, one with
HTMLWindow(WindowList.at(0))
The second one is a temporary created on the stack and is destroyed once you return from that method.

maddog_fr
8th August 2009, 09:40
It's exact.


WindowList.prepend(new HTMLWindow());

create a window that is not destroyed at the end of the method
but


WindowList.at(0).setGeometry(QRect(100,100,285,110 ));

generate this error : const class QPointer<HTMLWindow>' has no member named 'setGeometry'

I guess it's normal because the QList contains pointers to HTMLWindow(s) object
but how to use the object referenced by pointers ?

that's why i used HTMLWindow(WindowList.at(n)). it is how i do Typecast in Delphi.

faldzip
8th August 2009, 12:51
You should read some books about C++ basics I think...
And QPointer behaves in the same way as normal pointer, so getting back to one of the first lessons about C++ and pointers you will see that:
1. If you want to reference the member of the object you use '.' operator:


SomeClass obj;
obj.someMemberFunction();

2. But if you want to reference the member of the object, but you have only the pointer to that object, you have to use '->' operator:


SomeClass *obj = new SomeClass;
obj->someMemberFunction();


And a QPointer<SomeClass> behaves exactly in same way as SomeClass * so you have to use -> operator to get the members from object pointed by a QPointer.

But you are trying to do very weird things, which are not even supposed to work:


HTMLWindow(WindowList.at(n));

You are storing QPointer<HTMLWindow> in your list so:

WindowList.at(n)
returns a QPointer that points to some object of HTMLWindow class, and it can be used like normal pointer, so the line:


HTMLWindow(WindowList.at(n));

creates a new HTMLWindow object on a stack (a local variable in other words) with a existing HTMLWindow on index 'n' in your list as a parent because in that case the:


WindowList.at(n)

is casted to QWidget *, if constructor of the HTMLWindow looks like :


HTMLWindow(QWidget *parent);

And what you are trying to do is to cast the pointer to an object to instance of that object which obviously should fail, because how do you think the 32-bit (or more) integer value which the memory address of the object can be casted to that object, the whole HTMLWindow???

The next thing is that (as I said before) if this:


WindowList.at(0);

returns the first element of your list, which is of type QPointer, doing like this:


WindowList.at(0).setGeometry(QRect(100,100,285,110 ));

is trying to use the setGeometry() method of a QPointer object, which, as I suppose, does not have the setGeometry() method. If you want to use the setGeometry() of the HTMLWindow oobject pointed by this QPointer you have to use '->' operator:


WindowList.at(0)->setGeometry(QRect(100,100,285,110));


So, first of all, it is C++, not Delphi, so maybe you should find some time to learn some C++ basics before you start coding with it...

maddog_fr
8th August 2009, 17:48
You are right. I found out by myself that using -> instead of . was working
but i didnt really understand why.

I will follow your advice and take some information about c++ pointers that seems to be really different from delphi.

thx for ur help all.

maddog_fr
8th August 2009, 18:14
You should read some books about C++ basics I think...

So, first of all, it is C++, not Delphi, so maybe you should find some time to learn some C++ basics before you start coding with it...

Just for your information I am learning by example. Just reading a book is too boring.
Maybe it's a slower method but i am not sure. I learned Delphi without opening a book (just learned a bit turbo pascal at school when i was young). Throwning peoples sentences like "go to read C++ basics first" is not a good way to make people like a language. For me pointers are not basic part of C++. thx anyway.

faldzip
8th August 2009, 20:39
Pointers are used every where in C and C++, and especially in Qt where all your widgets should be made on heap and kept with pointer's - so learning about pointers is necessary. And reading a book can help you understand, why -> is working and . is not working.