PDA

View Full Version : qobject_cast() and typeid() problem



codeslicer
23rd January 2009, 22:40
Hello,

In my application, I have declared in the header file:


QWidget *activeWidget

activeWidget basically represents the QWidget in my application which has input focus. In my Edit menu, I have an option called Paste, and upon clicking that I want the text from the clipboard to be pasted into the activeWidget, which can be a reference to either QLineEdit or QPlainTextEdit. However, this code is incorrect:


connect(actionPaste, SIGNAL(triggered()), activeWidget, SLOT(paste()));

So, I have a function in my program called paste(). The new connection script is like this:


connect(actionPaste, SIGNAL(triggered()), this, SLOT(paste()));

In the paste() function, I want to use typeid() to determine the type of the activeWidget pointer, which can be either QLineEdit or QPlainTextEdit. Both support the paste() slot. So, I was thinking of doing something like:



activeWidget = someQLineEditWidget;

...

void MyApp::paste() {
qobject_cast<typeid(activeWidget*)>(activeWidget)->paste()
}

So what I am trying to do is to find the type of widget activeWidget is (in this example, QLineEdit) during runtime using typeid(), and then cast activeWidget to that type, and use the paste() function of the QLineEdit. But with that code I get a bunch of errors :(:


activeWidget cannot appear in a constant-expression
'typeid' operator cannot appear in a constant-expression

I know I can just check the type using "if" and "else" tags, but I want to try using typecasting as well, as it could be useful in the future.

Thanks in advance,
codeslicer :)

wysota
23rd January 2009, 23:08
This code is invalid - as the type identification is done at runtime, the compiler can't decide what function to call when building the code. The correct code is:


QLineEdit *le = qobject_cast<QLineEdit*>(activeWidget);
if(le) le->paste();
else {
QPlainTextEdit *pte = qobject_cast<QPlainTextEdit*>(activeWidget);
if(pte) pte->paste();
else qFatal("Unknown widget found");
}

Or a simple and brilliant abuse of one of Qt's features:

QMetaObject::invokeMethod(activeWidget, "paste");

which makes use of a fact that paste() is a slot in both classes.

codeslicer
23rd January 2009, 23:12
Thanks a lot, especially for the invokeMethod(); this will help a lot. :cool:

codeslicer
23rd January 2009, 23:14
It's just that the QLineEdit and QPlainTextEdit are made in Designer, but the 2nd code is all I need. :)

wysota
24th January 2009, 00:07
It's just that the QLineEdit and QPlainTextEdit are made in Designer,

I don't think that matters in any way. Or maybe I just don't see what you mean...