Hi. I am a bit new to C++ so i would like to ask if someone knows the following: I want to override only one method of a widget in Qt library. To do this i create my own class, which inherits that widget, and i declare just that one method in my new class. The problem is that the compiler (g++) complains about the constructors. Do i need also to override ALL the constructors of that widget? (there are many of them). If so, isn't there another way of implementing this? I mean just to override the method that i am interested in and not any other thing in that widget class. Thanks.
* Filippos Papadopoulos (csst9923@cs.uoi.gr) [20030514 11:10]:
I want to override only one method of a widget in Qt library. To do this i create my own class, which inherits that widget, and i declare just that one method in my new class. The problem is that the compiler (g++) complains about the constructors.
As my crystal ball is out for repair, could you please post the code g++ is complaining about together with g++'s warnings? Without seeing both there isn't much we could tell you. Philipp -- Philipp Thomas <pthomas@suse.de> SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nuremberg, Germany
On Wednesday 14 May 2003 11:10, Filippos Papadopoulos wrote:
I want to override only one method of a widget in Qt library. To do this i create my own class, which inherits that widget, and i declare just that one method in my new class. The problem is that the compiler (g++) complains about the constructors. Do i need also to override ALL the constructors of that widget? (there are many of them). If so, isn't there another way of implementing this? I mean just to override the method that i am interested in and not any other thing in that widget class.
You have to specify constructors for your classes derived of QWidget and related. Make sure you call the parent class constructor first. Otherwise most of the Qt internal stuff would not work. Most Qt classes intentionally don't provide a default constructor (one that does not receive any argument) because of this. You don't need all the variety of constructors that Qt classes provide, but at least one - preferably one that at least accepts a "parent" argument so the Qt widget hierarchy logic remains intact. As an added benefit, Qt will take care of cleaning up widgets that have a parent when you delete the parent (or the grandparent etc.). Example: class MyWidget: public QPushButton { Q_OBJECT MyWidget( QWidget * parent ); virtual ~MyWidget(); void myVeryCoolMethodThatDoesFancyThings(); }; Providing a virtual destructor is also a very good idea for classes that contain dynamically allocated memory (which all QWidgets do) - see http://cpptips.hyperformix.com/cpptips/why_virt_dtor2 CU -- Stefan Hundhammer <sh@suse.de> Penguin by conviction. YaST2 Development SuSE Linux AG Nuernberg, Germany
P.S.: The constructor definition looks like this: MyWidget::MyWidget( QWidget * parent ) : QPushButton( parent ) { ... // do your own init stuff here or leave empty if there is none } Make sure you call the parent class constructor (QPushButton in this example) first so the parent class part is initialized correctly. If you don't do that, prepare for some very interesting debugging sessions. ;-) CU -- Stefan Hundhammer <sh@suse.de> Penguin by conviction. YaST2 Development SuSE Linux AG Nuernberg, Germany
Philipp Thomas wrote:
As my crystal ball is out for repair, could you please post the code g++ is complaining about together with g++'s warnings? Without seeing both there isn't much we could tell you.
Ok i post my code then, see below :) Stefan Hundhammer wrote:
You have to specify constructors for your classes derived of QWidget and related. Make sure you call the parent class constructor first. Otherwise most of the Qt internal stuff would not work.
Most Qt classes intentionally don't provide a default constructor (one that does not receive any argument) because of this.
You don't need all the variety of constructors that Qt classes provide, but at least one - preferably one that at least accepts a "parent" argument so the Qt widget hierarchy logic remains intact. As an added benefit, Qt will take care of cleaning up widgets that have a parent when you delete the parent (or the grandparent etc.).
I hope i am correct in my following code. I want to override only paintCell of QListViewItem class. /******** myListViewItem.h ******/ #ifndef MY_LIST_VIEW_ITEM_H #define MY_LIST_VIEW_ITEM_H #include <qlistview.h> #include <qstring.h> #include <string> #include <iostream> class myListViewItem : public QListViewItem { public: myListViewItem(QListView * parent, QString, QString ,QString , QString , QString , QString , QString , QString ); myListViewItem(myListViewItem * parent, QString, QString ,QString , QString , QString , QString , QString , QString ); myListViewItem(myListViewItem * parent ); void paintCell ( QPainter * p, const QColorGroup & cg, int column, int width, int align ); }; #endif /***************************************************/ /******** myListViewItem.cpp ******/ #include "myListViewItem.h" myListViewItem::myListViewItem( QListView * parent, QString s1, QString s3 = QString::null, QString s4 = QString::null, QString s5 = QString::null, QString s6 = QString::null, QString s7 = QString::null, QString s8 = QString::null, QString s9 = QString::null ) :QListViewItem(parent, s1) { ; } myListViewItem::myListViewItem( myListViewItem * parent, QString s1, QString s3 = QString::null, QString s4 = QString::null, QString s5 = QString::null, QString s6 = QString::null, QString s7 = QString::null, QString s8 = QString::null, QString s9 = QString::null ) :QListViewItem(parent, s1) { ; } myListViewItem::myListViewItem(myListViewItem * parent ) :QListViewItem(parent) { ; } void myListViewItem::paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align) { //do some funny stuff here... } /*****************************************************/ So i do the following in another source file: myListViewItem* itemChild; vector <QString> neededLibVector; new myListViewItem(itemChild, neededLibVector[i].ascii()); so the compiler says : no matching function for call to `myListViewItem::myListViewItem(myListViewItem*&, const char*)' myListViewItem.h:11: candidates are: myListViewItem::myListViewItem(const myListViewItem&) myListViewItem.h:22: myListViewItem::myListViewItem(myListViewItem*) myListViewItem.h:20: myListViewItem::myListViewItem(myListViewItem*, QString, QString, QString, QString, QString, QString, QString, QString) myListViewItem.h:16: myListViewItem::myListViewItem(QListView*, QString, QString, QString, QString, QString, QString, QString, QString) The point is that when i do : QListViewItem* itemChild; vector <QString> neededLibVector; new QListViewItem(itemChild, neededLibVector[i].ascii()); the compiler is happy about it ... Thanks. Filip
On Thursday 15 May 2003 00:04, Filippos Papadopoulos wrote:
/******** myListViewItem.h ******/ #ifndef MY_LIST_VIEW_ITEM_H #define MY_LIST_VIEW_ITEM_H
#include <qlistview.h> #include <qstring.h> #include <string> #include <iostream>
class myListViewItem : public QListViewItem { public: myListViewItem(QListView * parent, QString, QString ,QString , QString , QString , QString , QString , QString );
This is where the default arguments should go: myListViewItem( QListView * parent, QString s1, QString s3 = QString::null, QString s4 = QString::null, QString s5 = QString::null, QString s6 = QString::null, QString s7 = QString::null, QString s8 = QString::null, QString s9 = QString::null ) In the .h file, not in the .cpp file! BTW it might be a good idea to use 'const QString &' here everywhere. It saves a lot of overhead avoiding to create temporary objects just for calling this function.
myListViewItem(myListViewItem * parent, QString, QString ,QString , QString , QString , QString , QString , QString );
myListViewItem(myListViewItem * parent );
You wouldn't need that one at all if you'd specify a default argument for s1 as well. In that case, a call to 'myListViewItem( myListViewItem *)' without anything else would expand to 'myListViewItem( myListViewItem *, QString::null, QString::null, ...)'.
/******** myListViewItem.cpp ******/
#include "myListViewItem.h"
myListViewItem::myListViewItem( QListView * parent, QString s1, QString s3 = QString::null, QString s4 = QString::null, QString s5 = QString::null, QString s6 = QString::null, QString s7 = QString::null, QString s8 = QString::null, QString s9 = QString::null
Wrong place for specifying default arguments (= QString::null) ! Doesn't the compiler complain about that? Those default args should go to the function declaration (the .h file), not the function definition (the .cpp file)! I am not absolutely sure, but I think the default arguments here are simply ignored.
)
:QListViewItem(parent, s1)
Make sure you pass s2, s3, s4 etc. to the parent constuctor - otherwise having s2, s3, s4 etc. here wouldn't make too much sense.
So i do the following in another source file:
myListViewItem* itemChild; vector <QString> neededLibVector; new myListViewItem(itemChild, neededLibVector[i].ascii());
so the compiler says :
no matching function for call to `myListViewItem::myListViewItem(myListViewItem*&, const char*)' myListViewItem.h:11: candidates are: myListViewItem::myListViewItem(const myListViewItem&) myListViewItem.h:22: myListViewItem::myListViewItem(myListViewItem*) myListViewItem.h:20: myListViewItem::myListViewItem(myListViewItem*, QString, QString, QString, QString, QString, QString, QString, QString) myListViewItem.h:16: myListViewItem::myListViewItem(QListView*, QString, QString, QString, QString, QString, QString, QString, QString)
...and he is perfectly right: Having specified the default args in the function definition (the .cpp file) rather in the function declaration (the .h file), you don't have a function that could be called with one myListViewItem pointer and one QString. Your default args in the function declaration are ignored, any so you only have a version with a myListViewItem pointer and a lot of QString arguments - and all the others that don't match at all here.
The point is that when i do :
QListViewItem* itemChild; vector <QString> neededLibVector; new QListViewItem(itemChild, neededLibVector[i].ascii());
the compiler is happy about it ...
Sure, because the TrollTech folks did it right and put the default args where they belong... ;-) BTW beware about QString::ascii() that you seem to be using here -- it tends to make a bad mess about internationalized messages. That may be good enough for our friends in the USA (where everything is perfect as long as 7-bit ASCII works, the currency is $ and the time zone defaults to Pacific Time), but for us "old Europeans" things are not so easy... tried using that in your native Greek? Does it still work then? ;-) CU -- Stefan Hundhammer <sh@suse.de> Penguin by conviction. YaST2 Development SuSE Linux AG Nuernberg, Germany
On Thu, 15 May 2003, Stefan Hundhammer wrote:
...and he is perfectly right: Having specified the default args in the function definition (the .cpp file) rather in the function declaration (the .h file), you don't have a function that could be called with one myListViewItem pointer and one QString. Your default args in the function declaration are ignored, any so you only have a version with a myListViewItem pointer and a lot of QString arguments - and all the others that don't match at all here.
Ok that was the mistake , thanks a LOT !
BTW beware about QString::ascii() that you seem to be using here -- it tends to make a bad mess about internationalized messages. That may be good enough for our friends in the USA (where everything is perfect as long as 7-bit ASCII works, the currency is $ and the time zone defaults to Pacific Time), but for us "old Europeans" things are not so easy... tried using that in your native Greek? Does it still work then? ;-)
Thanks for the i18n advice, it will be useful for the future ,this is for sure ! Filip.
participants (3)
-
Filippos Papadopoulos
-
Philipp Thomas
-
Stefan Hundhammer