PDA

View Full Version : [SOLVED] How to add tabs dynamically to a QTabWidget?



madcat2709
26th March 2009, 14:31
Hey Guys!

As you all can see I'm new to Qt and to this forum so please be patient with me ;-)
After playing around with a few tutorials I considered myself to be able to design a mainwindow-application that features dynamic tabs. That's means I want to allow the user to add a new instance of a predesigned tab while the program is running. I used the Qt Designer to build the forms. So here is my code, I hope you guys can help me. Thank you for your attention.

The QAction "actionNeues_PlotTab" is part of the menubar in the mainwindow and after compiling it runs correctly, means I get to read my qDebug messages. So it's basicly all about the addPlotTab() slot I guess. The Ui_PlotTab class is also something I generated with the Qt Designer and hopefully adds the right child-widgets to the one widget that will become my new tab.

Compiling doesn't make any trouble but when running and using the menubar entry that should reveal a new tab nothing happens although the new tabs seem to have an index.

mainwindowimpl.h

#ifndef MAINWINDOWIMPL_H
#define MAINWINDOWIMPL_H
//
#include <QMainWindow>
#include "ui_mainwindow.h"
//
class MainWindowImpl : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
public:
MainWindowImpl( QWidget * parent = 0, Qt::WFlags f = 0 );
private slots:
void addPlotTab();
};
#endif

mainwindowimpl.cpp

#include "mainwindowimpl.h"
#include "ui_plottab.h"
#include <QtGui>
//
MainWindowImpl::MainWindowImpl( QWidget * parent, Qt::WFlags f)
: QMainWindow(parent, f)
{
setupUi(this);

connect(actionNeues_PlotTab, SIGNAL(activated()), this, SLOT(addPlotTab()));
}
//
void MainWindowImpl::addPlotTab()
{
QWidget NewTab;
QString name="NewTab";
Ui_PlotTab Ui_NewTab;
Ui_NewTab.setupUi(&NewTab);;
tabWidget->setUpdatesEnabled(true);
tabWidget->addTab(&NewTab, name);
int a = tabWidget->indexOf(&NewTab);
QWidget NewTab2;
QString name2="NewTab2";
Ui_NewTab.setupUi(&NewTab2);
tabWidget->addTab(&NewTab2, name2);
int b = tabWidget->indexOf(&NewTab2);
qDebug() << "I'm still not working!" << a << "\t" << b;
};

main.cpp
#include <QApplication>
#include "mainwindowimpl.h"
//
int main(int argc, char ** argv)
{
QApplication app( argc, argv );
MainWindowImpl win;
win.show();
app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
return app.exec();
}

Lykurg
26th March 2009, 16:46
void MainWindowImpl::addPlotTab()
{
QWidget NewTab;
QString name="NewTab";
Ui_PlotTab Ui_NewTab; //created
Ui_NewTab.setupUi(&NewTab);;
tabWidget->setUpdatesEnabled(true);
tabWidget->addTab(&NewTab, name);
int a = tabWidget->indexOf(&NewTab);
QWidget NewTab2;
QString name2="NewTab2";
Ui_NewTab.setupUi(&NewTab2);
tabWidget->addTab(&NewTab2, name2);
int b = tabWidget->indexOf(&NewTab2);
qDebug() << "I'm still not working!" << a << "\t" << b;
}//destroyed!

Hi,

you have to create your object on the heap with new! because the way you do (creating on the stack), the new pages will be deleted at the end of the scope.

Lykurg

madcat2709
26th March 2009, 17:27
Thank very much you for your fast answer!
I've had that exact problem before at some other point and did not even think about it...
Hopefully I learned now! Same think with my QWidget Instance - to remain after the scope they all need to be on heap ;-)

aloha
6th April 2009, 18:18
Hello, i recently started with qt and i wanted to insert tabs dynamically whenever i pressed a centrain button.
I've based myself on the code above, but it doenst succeed 100%

i can insert new tabs when clicking that button but the ui/layout is not what i defined in the designer. In fact there is no 'design', only new tabs can be inserted.
I have created a ui using the designer and did the same thing the guy above did.

The coded i've corrected a bit :


QWidget NewTab;
QString name="NewTab";
Ui_PlotTab *Ui_NewTab= new Ui_PlotTab; // This is implemented
Ui_NewTab->setupUi(NewTab); //but makes no difference when i delete these lines
tabWidget->addTab(NewTab, name);


i cant seem to find my/his mistake.
Why is QT just adding a new tab and not using my ui in that tab?

thank you very much!

madcat2709
6th April 2009, 19:35
Hey!

Im for sure not a professional at these issus but to me at first it wasn't clear that I have to design the layout of my tabs not at the first tab that the TabWidget in the Designer shows. One has to create another Designer file with the Widget draft of the Designer and create an whole independent UI. In the lines you've deletet I used to create a new QWidget, fill it with this mentioned independent layout and put this Widget afterwards into a new tab.

So if you have only designed the layout of your first tab the new tabs will only contain empty widgets and apear to be amtpy tabs. You have to fill them with Widgets that already contain an UI.

Maybe that's the point maybe not. Hope it will help you ;-)

aloha
6th April 2009, 19:54
Thank you for your reply
i have added a screenshot to show you where i'm at :-)

as you can see: i can dynamically add tabs using your code
(btw: i havent deleted those lines, it was just to show it didn't make any difference)
but then it doesnt load the ui i created and which you can also see in the screenshot.

my code is:


QWidget *NewTab=new QWidget(this);
const QString name(name.c_str());
Ui_Form * Ui_NewTab=new Ui_Form; //This is the ui file for the ui in the screen
Ui_NewTab->setupUi(NewTab);
tabWidget->addTab(NewTab, name);

aloha
7th April 2009, 10:57
This is what i have created



QWidget *NewTab=new QWidget(this); // create tab
const QString names(name.c_str());
intensityframe2 * w=new intensityframe2(NewTab); // fill the tab with my design
w->show(); // show it
tabWidget->addTab(NewTab, names); // and add it to the tab holder


output:
it creates the tab, but does not doesnt add my layout to it; it's just an empty tab.
Although, when i change 'NewTab' on line 3 to 'this', it draws my ui in the mainscreen, which offcourse isnt the purpose but then i know the ui wasnt the problem.

The design i use in the tab is inherited from QFrame

Can anybody tell why it isnt showing my layout in the tab?

ComaWhite
8th April 2009, 08:42
QWidget *NewTab = new QWidget(this); // create tab
const QString names(name.c_str());
intensityframe2 * w=new intensityframe2(NewTab); // fill the tab with my design
w->show(); // show it
tabWidget->addTab(NewTab, names); // and add it to the tab holdertry this


tabWidget->addTab(new Intensityframe2, name.c_str());
If your class inherits QObject, just pass this to Intensityframe2 instead of create a redundant QWidget. But when you add the widget to addTab(). The tabwidget will take control of ownership if you had read the documentation on QTabWidget and calls show itself too. I don't know why you're using c_str() and casting to const when you can just pass it to the constructor as is. and QWidget *parent should be the last parameter in the constructor not the first just so you can add a parent of the object or not. and have a default value of 0. QWidget *parent = 0; And just new the IntensityFrame2 inside the constructor unless you need to do stuff with it and add a QList to hold it.