0

Lets say there are 3 classes Foo1, Foo2 and Foo3. They are inherit QWidget. I now place each of them info a QTabWidget object.

QWidget* foo1 = new Foo1();
ui->tbMain->addTab(foo1, "Untitled*");

QWidget* foo2 = new Foo2();
ui->tbMain->addTab(foo2, "Untitled*");

QWidget* foo3 = new Foo3();
ui->tbMain->addTab(foo3, "Untitled*");

Now I select different tabs and a signal is emited and this slot catches it:

void MainWindow::on_tbMain_currentChanged(int index)
{
     QWidget* widget = ui->tbMain->widget(index);
}

I can retrieve the object that is in the currently selected tab. But i can retrieve it as QWidget, and I need to know either it is type Foo1, Foo2 or Foo3? How can I do that? I would apreciate all help!

Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74

3 Answers3

1

You can access the original class name with ->metaObject()->className()

Example:

QWidget* foo1 = new Foo1();
qDebug() << foo1->metaObject()->className();

// will print "Foo1"

if(QString(foo1->metaObject()->className()) == "Foo1") {
    Foo1* f1 = qobject_cast<Foo1*>(foo1)
}

Or use qobject_cast<> and check return value.

QWidget* foo2 = new Foo2();
Foo1* f2 = qobject_cast<Foo1*>(foo2);

// f2 == NULL
Miki
  • 40,887
  • 13
  • 123
  • 202
1

You can use this:

void MainWindow::on_tbMain_currentChanged( int index )
{
    QWidget* widget = ui->tbMain->widget( index );

    if ( auto foo1 = dynamic_cast< Foo1* >( widget ) )
    {
        // If the cast is successful it is a Foo1 object. And you call it's functions.
        // ...
    }
    else if ( auto foo2 = dynamic_cast< Foo2* >( widget ) )
    {
        // ...
    }
    else if ( auto foo3 = dynamic_cast< Foo3* >( widget ) )
    {
        // ...
    }
}

But if there is a common property for those Foo* classes which you want to use, than it would be more elegant if you create a FooBase class and than derive the Foo1 ... classes from that. In this case you only need to cast once.

class FooBase : public QWidget
{
public:
    virtual void set( /**/ ) = 0;
};

class Foo1 : public FooBase
{
public:
    virtual void set( /**/ ) { qDebug() << "Foo1::set()"; }
};

Then you could write this:

void MainWindow::on_tbMain_currentChanged( int index )
{
    auto foo = dynamic_cast< FooBase* >( ui->tbMain->widget( index ) );
    if ( foo )
    {
        foo->set( /**/ );
    }
}
p.i.g.
  • 2,815
  • 2
  • 24
  • 41
  • Hi there, I actually have it done like you presented. I have a base class that derives qwidget and further classes that derive from base class. I will try this second way, thank you. Is there a clean way of checking which foo subclass are you if for example one of that classes had some extra method and I needed it? Is it your first code example? – Łukasz Przeniosło Jul 12 '15 at 07:47
0

You can use setObjectName to identify the objects in QT. It can be used as below :

QWidget* foo1 = new Foo1();
foo1->setObjectName("Foo1");

To get back the Identity of object you can use

QString myObjName = foo1->objectName()
Amol Saindane
  • 1,568
  • 10
  • 19