Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-jambi-interest Archive, August 2006
Override problem


Message 1 in thread

Hello,

I get this

"Non-virtual function overridden: Function 'addAction' in class 
'com.poseidon.rescue.client.student.LoginPage$1'" 
(com.trolltech.qt.QNonVirtualOverridingException)
    at 
com.trolltech.qt.gui.QPushButton.__qt_QPushButton_String_QWidget(Native 
Method)
    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:24)
    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:20)
    at 
com.poseidon.rescue.client.student.LoginPage$1.<init>(LoginPage.java:50)
    at 
com.poseidon.rescue.client.student.LoginPage.<init>(LoginPage.java:49)

when I try to do this in my code:

        QPushButton loginButton = new QPushButton("Login") {
            public void addAction(QAction qAction) {
                QAction action = 
ActionFactory.getAction((LoginAction.class.getName()));
                this.clicked.connect(action, "actionPerformed()");
            }
        };

I'm used to be able to change such default behaviour, but not in Jambi?

Best regards,
Helge Fredriksen


Message 2 in thread

Helge Fredriksen wrote:
> Hello,
> 
> I get this
> 
> "Non-virtual function overridden: Function 'addAction' in class 
> 'com.poseidon.rescue.client.student.LoginPage$1'" 
> (com.trolltech.qt.QNonVirtualOverridingException)
>    at 
> com.trolltech.qt.gui.QPushButton.__qt_QPushButton_String_QWidget(Native 
> Method)
>    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:24)
>    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:20)
>    at 
> com.poseidon.rescue.client.student.LoginPage$1.<init>(LoginPage.java:50)
>    at 
> com.poseidon.rescue.client.student.LoginPage.<init>(LoginPage.java:49)
> 
> when I try to do this in my code:
> 
>        QPushButton loginButton = new QPushButton("Login") {
>            public void addAction(QAction qAction) {
>                QAction action = 
> ActionFactory.getAction((LoginAction.class.getName()));
>                this.clicked.connect(action, "actionPerformed()");
>            }
>        };
> 
> I'm used to be able to change such default behaviour, but not in Jambi?

Hi Helge,

addAction is not a virtual function in C++, so ideally it would be 
declared as final in Java. However, since som subclasses of QWidget 
override addAction as a non virtual function, thus shadowing the 
original function. Java does not allow shadowing of final functions, so 
we needed to make the functions play together. This works by making the 
original function appear virtual in java, and then give you a runtime 
error if you actually override this function at runtime.

If you want a addAction to behave differently you will have to use name 
it differently and use a non-anonymous class for it so that the function 
actually becomes callable.

Best regards,
Gunnar


Message 3 in thread

Gunnar Sletta wrote:
> Helge Fredriksen wrote:
>> Hello,
>>
>> I get this
>>
>> "Non-virtual function overridden: Function 'addAction' in class 
>> 'com.poseidon.rescue.client.student.LoginPage$1'" 
>> (com.trolltech.qt.QNonVirtualOverridingException)
>>    at 
>> com.trolltech.qt.gui.QPushButton.__qt_QPushButton_String_QWidget(Native 
>> Method)
>>    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:24)
>>    at com.trolltech.qt.gui.QPushButton.<init>(QPushButton.java:20)
>>    at 
>> com.poseidon.rescue.client.student.LoginPage$1.<init>(LoginPage.java:50)
>>    at 
>> com.poseidon.rescue.client.student.LoginPage.<init>(LoginPage.java:49)
>>
>> when I try to do this in my code:
>>
>>        QPushButton loginButton = new QPushButton("Login") {
>>            public void addAction(QAction qAction) {
>>                QAction action = 
>> ActionFactory.getAction((LoginAction.class.getName()));
>>                this.clicked.connect(action, "actionPerformed()");
>>            }
>>        };
>>
>> I'm used to be able to change such default behaviour, but not in Jambi?
>
> Hi Helge,
>
> addAction is not a virtual function in C++, so ideally it would be 
> declared as final in Java. However, since som subclasses of QWidget 
> override addAction as a non virtual function, thus shadowing the 
> original function. Java does not allow shadowing of final functions, 
> so we needed to make the functions play together. This works by making 
> the original function appear virtual in java, and then give you a 
> runtime error if you actually override this function at runtime.
>
> If you want a addAction to behave differently you will have to use 
> name it differently and use a non-anonymous class for it so that the 
> function actually becomes callable.

Yes, I did this already.

PS: I might see a lack of functionality in your action framework. I'm 
used to be able to tie actions also to buttons, but this
seem not to exist in Qt's QAction which can only be tied to toolbar and 
menues. I'm trying to make my own
bridge between QActions and QButtons using signals, but I'm stuck in 
small details like how to couple setEnabled in
buttons and actions. Does there exist a way to transfer an enabled 
signal from a QAction to a QWidget?

Helge F.



Message 4 in thread

Helge Fredriksen wrote:

> I might see a lack of functionality in your action framework. I'm 
> used to be able to tie actions also to buttons, but this
> seem not to exist in Qt's QAction which can only be tied to toolbar and 
> menues. I'm trying to make my own
> bridge between QActions and QButtons using signals, but I'm stuck in 
> small details like how to couple setEnabled in
> buttons and actions. Does there exist a way to transfer an enabled 
> signal from a QAction to a QWidget?

Hi Helge,

You can use a QToolButton for this and set its default action to the 
action you want to use.

QToolButton toolButton = new QToolButton();
toolButton.setDefaultAction(action);

I hope this helps ;-)

-
Gunnar


Message 5 in thread

On Thursday 24 August 2006 09:38, Gunnar Sletta wrote:
> addAction is not a virtual function in C++, so ideally it would be
> declared as final in Java. However, since som subclasses of QWidget
> override addAction as a non virtual function, thus shadowing the
> original function. Java does not allow shadowing of final functions, so
> we needed to make the functions play together. This works by making the
> original function appear virtual in java, and then give you a runtime
> error if you actually override this function at runtime.

I'm not sure I follow this.
The QWidget has a   void addAction(QAction); method.
Some classes have an addAction method but have different arguments. Which 
makes it a different method.
Its perfectly legal to have

QWidget:
 final void addAction(QAction action);
QToolBar:
 final QAction addAction(String string);

See attached source file.
-- 
 [ signature omitted ] 
class QAction {
}

class QWidget {
    final void addAction(QAction action) {}
}

class QToolBar extends QWidget {
    final QAction addAction(String string) {
        return new QAction();
    }
}

Attachment:

Attachment: pgp8dL7TUkltf.pgp
Description: PGP signature


Message 6 in thread

Thomas Zander wrote:
> On Thursday 24 August 2006 09:38, Gunnar Sletta wrote:
> 
>>addAction is not a virtual function in C++, so ideally it would be
>>declared as final in Java. However, since som subclasses of QWidget
>>override addAction as a non virtual function, thus shadowing the
>>original function. Java does not allow shadowing of final functions, so
>>we needed to make the functions play together. This works by making the
>>original function appear virtual in java, and then give you a runtime
>>error if you actually override this function at runtime.
> 
> 
> I'm not sure I follow this.
> The QWidget has a   void addAction(QAction); method.
> Some classes have an addAction method but have different arguments. Which 
> makes it a different method.
> Its perfectly legal to have
> 
> QWidget:
>  final void addAction(QAction action);
> QToolBar:
>  final QAction addAction(String string);

True, but if you look at qtoolbar.h you will see that it also reimplements

void addAction(QAction *action);

Which is what is causing the problem in this particular case.

-
Gunnar


Message 7 in thread

On Thursday 24 August 2006 11:37, Gunnar Sletta wrote:
> > I'm not sure I follow this.
> > The QWidget has a   void addAction(QAction); method.
> > Some classes have an addAction method but have different arguments.
> > Which makes it a different method.
> > Its perfectly legal to have
> >
> > QWidget:
> >  final void addAction(QAction action);
> > QToolBar:
> >  final QAction addAction(String string);
>
> True, but if you look at qtoolbar.h you will see that it also
> reimplements
>
> void addAction(QAction *action);
>
> Which is what is causing the problem in this particular case.

Hmm?
/me looking again.

Aha, its not in the APi docs because its a workaround for certain 
compile-options;

#ifdef Q_NO_USING_KEYWORD
    inline void addAction(QAction *action)
    { QWidget::addAction(action); }
#else
    using QWidget::addAction;
#endif

Hmm, I'm not sure when that is used, but I guess its important enough to 
effect the design of the Jambi API. ;-)

-- 
 [ signature omitted ] 

Attachment: pgpm6Y8zMv76U.pgp
Description: PGP signature


Message 8 in thread

Thomas Zander wrote:

> Hmm?
> /me looking again.
> 
> Aha, its not in the APi docs because its a workaround for certain 
> compile-options;
> 
> #ifdef Q_NO_USING_KEYWORD
>     inline void addAction(QAction *action)
>     { QWidget::addAction(action); }
> #else
>     using QWidget::addAction;
> #endif
> 
> Hmm, I'm not sure when that is used, but I guess its important enough to 
> effect the design of the Jambi API. ;-)
> 

Yeah... I C++ the function addAction(QAction *) is shadowed by the other 
overloads so unless you make use of using QWidget::addAction() or the 
inline approach you won't be able to call addAction(QAction *) on a 
toolbar. The solution for C++ is to "implement the function again" in 
the subclass, as you see above. So in Qt / C++ you never notice, because 
we've fixed all these cases. Qt Jambi on the other hand has to carry the 
burden of that ;-(

In practice this shouldn't cause to much of a problem though. You might 
stumble into it once, and then you get the verbose exception and don't 
do it again.

-
Gunnar