PDA

View Full Version : QTabWidget with same tabs



Djony
9th January 2007, 11:04
Hi! I am using qtabwidget to show some data, and I need to dinamicaly add tabs. Each tabs need to have same widgets (couple of qlinedits, qtablewidget, groupbox etc...) How can I add tabs with same objects on it, without drawing manually objects on every new tab?

momesana
9th January 2007, 11:37
Create a QWidget derived class with the lineedits and further GUI-Elements you need for the page and introduce a function to create an Object of this class whenever a new tab is requested and then insert/append this widget as a new page into the QTabWidget.

Djony
9th January 2007, 15:30
Thanx for reply, I did that, but I get a wierd behaviour from my application. I am using this code to generate my qtabwidget
tabTCDescription=new QTabWidget(this);
tabTCDescription->addTab(new Platform(),"Platform_0");
//Platform is my class which inherits QWidget
tabTCDescription->setGeometry(QRect(260, 230, 431, 311));
//tabTCDescription is qtabwidget

When I run this code in constructor, tabwidget is shown. When I put it in my slot method (where I need it actually) it doesn't show tabwidget. What am I doing wrong?

guilugi
9th January 2007, 18:10
Hi,

In your slot function, you're running all these lines ?
If so, you're creating a new TabWidget each time the slot is called..
You have to create a single tabwidget for the whole class in your constructor, and only call addTab() in your slot!

Djony
10th January 2007, 12:07
Hi! I solved that, you are right. But there is a different workaround (btw, I am deleting tabwidget in the same slot, so I can create it). The workaround is to call show() method when the tabwidget is created. It works fine for me. I have different problem now. I have created class which inherits QWidget. Now, this class has those QLineEdits and other elements. When I create several tabs I can't really acces the appropriate tab to fill the right data. This is my code


//this is how I add tab
platformTab=new Platform(tabTCDescription);
//Platform is my class which inherits QWidget, tabTCDescription is pointer on QTabWidget
tabTCDescription->addTab(platformTab,"somestring");

//this is how I try to access appropriate Platform class to fill QLinedit:
tempPlatformTab=(Platform*)tabTCDescription->widget(someinteger);
//checked the someinteger, it is OK
//and this is how I try to fill QLineEdit on my tab
tempPlatformTab->editPlatformType->setText(tempString);
//editPlatformType is QLineEdit

The result of code above is that all tabs are filled with same data. What I need to do, to access the appropriate tab?

guilugi
10th January 2007, 12:46
That's strange... you should check the last index, just after you inserted your tab!

Something like widget( tabTCdescription->count()-1 ) should return you the last tab...

Djony
10th January 2007, 13:11
Thanks for advice but it doesn't work. My index is OK, tried it. I don't know what I am doing wrong. Here is my Platform class which inherits widget


class Platform : public QWidget
{
Q_OBJECT
public:
QLabel * labelPlatformType;
QLineEdit * editPlatformType;
QLabel * labelActivatedStatus;
QLineEdit * editActivatedStatus;
QLabel * platformOS;
QLineEdit * editPlatformOS;
QLabel * timeout;
QLineEdit * editTimeout;

Platform( QWidget *parent = 0);
virtual ~Platform();
};

//this is constructor

Platform::Platform(QWidget *parent): QWidget(parent)
{
labelPlatformType= new QLabel(tr("Platform Type :"));
labelPlatformType->setParent(parent);
labelPlatformType->setGeometry(QRect(20, 30, 80, 18));
editPlatformType= new QLineEdit(parent);
editPlatformType->setGeometry(QRect(100, 30, 113, 18));
labelActivatedStatus= new QLabel(tr("Activated Status :"));
labelActivatedStatus->setParent(parent);
labelActivatedStatus->setGeometry(QRect(20, 50, 100, 18));
editActivatedStatus= new QLineEdit(parent);
editActivatedStatus->setGeometry(QRect(130, 50, 81, 18));
platformOS= new QLabel(tr("Platform OS :"));
platformOS->setParent(parent);
platformOS->setGeometry(QRect(250, 30, 100, 18));
editPlatformOS= new QLineEdit(parent);
editPlatformOS->setGeometry(QRect(332, 30, 91, 18));
timeout= new QLabel(tr("Timeout :"));
timeout->setParent(parent);
timeout->setGeometry(QRect(250, 50, 100, 18));
editTimeout= new QLineEdit(parent);
editTimeout->setGeometry(QRect(310, 50, 113, 18));
}
Maybe you got some new ideas? I don't know whats wrong here :(

guilugi
10th January 2007, 13:36
Hard to tell just by seeing this code...it would be helpful if I had a compilable source code !

Djony
10th January 2007, 14:27
Well, i've pasted all code related to qtabwidget. I've noticed another thing now. When I run my application (i use Eclipse) i get this warning in console:

QLayout::addChildWidget: Platform "" in wrong parent; moved to correct parent Maybe this gives hints to someone...

Gopala Krishna
10th January 2007, 14:59
Hi! I solved that, you are right. But there is a different workaround (btw, I am deleting tabwidget in the same slot, so I can create it).

Can you show the code of this slot ? I guess you are doing something wrong in this slot. (Not sure , though).
Also to which signal is this slot connected ?

Djony
10th January 2007, 15:02
No, I solved that. It's not about showing qtabwidget anymore. It's about writing the same data on all tabs (which is wrong, offcourse).

guilugi
10th January 2007, 15:10
Djony,

If you can't, or if you don't want to send us your code, no problem, I understand ! :p

But, could you make just a small sample code with your tab classes, independent from your application, that we can compile and debug ?

This would be faster to help, because I can't point the issue with your samples...

Gopala Krishna
10th January 2007, 15:12
When I create several tabs I can't really acces the appropriate tab to fill the right data. This is my code


//this is how I try to access appropriate Platform class to fill QLinedit:
tempPlatformTab=(Platform*)tabTCDescription->widget(someinteger);
//checked the someinteger, it is OK
//and this is how I try to fill QLineEdit on my tab
tempPlatformTab->editPlatformType->setText(tempString);
//editPlatformType is QLineEdit

The result of code above is that all tabs are filled with same data. What I need to do, to access the appropriate tab?


Ok, where are you calling these functions ? In the same slot ?? If so it would help if you show your slot code and show to which signal the slot is connected to.

Djony
10th January 2007, 16:33
Actually, I solved it, it is very simple. If you look at code of constructor of Platform class, you will see that I use setParent(parent) with my edit controls. Well, I changed it all to setParent(this) and it works. Before that I tried not to set parent and it doesn;t work. So, solution is simple, it has nothing to do with my slot code :) Thanks for your effort guys!

guilugi
10th January 2007, 16:39
Oh yes, I didn't even noticed that ! :)

I'm not even sure you need to use those setParent() calls...

gfunk
10th January 2007, 19:43
Yeah, instead of


labelPlatformType= new QLabel (http://doc.trolltech.com/4.2/QLabel.html)(tr("Platform Type :"));
labelPlatformType->setParent(this);


You can just do



labelPlatformType= new QLabel (http://doc.trolltech.com/4.2/QLabel.html)(tr("Platform Type :"), this);

momesana
11th January 2007, 16:33
If that is really the entire constructor code of your Platform class, that means you are not using Layouts which in turn means you are doing something fundemantally wrong. If that is really the case you should introduce some layout within the Platform class and set the main layout of the Platform class to this. I didn't get to follow the thread yesterday, but as I started to read the posts today I noticed the wierd parent-child constructs. For the platform you have introduced, a QGridLayout is sufficient and appropriate.
You don't need to declare Parents for the widgets since they are automatically reparented when adding them to the layout. So the correct way to do this, is to instantiate the desired Widgets and then to create a Layout and make it the main Layout of the Platform object.

QGridLayout * lo = new QGridLayout;
setLayout(lo);

lo->addWidget(label, ....);
Layouts are a very very important Part of Qt's Gui Programming. Generally, you have at least one Layout in your class, if it has more than one widget to be laid out ...


cheers
momesana

dipen
23rd December 2011, 11:49
Hi! I solved that, you are right. But there is a different workaround (btw, I am deleting tabwidget in the same slot, so I can create it). The workaround is to call show() method when the tabwidget is created. It works fine for me. I have different problem now. I have created class which inherits QWidget. Now, this class has those QLineEdits and other elements. When I create several tabs I can't really acces the appropriate tab to fill the right data. This is my code


//this is how I add tab
platformTab=new Platform(tabTCDescription);
//Platform is my class which inherits QWidget, tabTCDescription is pointer on QTabWidget
tabTCDescription->addTab(platformTab,"somestring");

//this is how I try to access appropriate Platform class to fill QLinedit:
tempPlatformTab=(Platform*)tabTCDescription->widget(someinteger);
//checked the someinteger, it is OK
//and this is how I try to fill QLineEdit on my tab
tempPlatformTab->editPlatformType->setText(tempString);
//editPlatformType is QLineEdit

The result of code above is that all tabs are filled with same data. What I need to do, to access the appropriate tab?




Hi, How did you solved that? I'm facing the similar problem, getting segmentation fault (using windows Qt-4.7.4) while trying to insert or add same object in different tabs.

code:
static int tabIndex;
PageInsideTab *ptr; // PageInsideTab is inherited from QWidget
ptr = pageList.at(tabIndex); // QList <PageInsideTab *> pageList - I declared 15 pointers and stored into this list
ptr = new PageInsideTab(tabWidget);
qDebug()<<"tabIndex="<<tabIndex;
tabWidget->insertTab(tabIndex, ptr, name); // name is QString
// tabWidget->addTab(ptr, name);
tabIndex++;


when this slot is running first time one tab is inserted, all ok, but in the second run I'm getting seg. fault.
Any solution please?

amleto
23rd December 2011, 12:10
because you are assigning the new page to a COPY of the pointer in the list.

I strongly advise that you not populate your list with invalid pointers. Instead, append to your list when you have a valid pointer to add.

dipen
24th December 2011, 12:02
Hi,
As It's confidential, I'm only giving the relevant code.

I created a form PageInsideTab.ui which is inherited from QWidget and I put a button and a textEdit on it.
Now the header file:
#ifndef CHATWINDOW_H
#define CHATWINDOW_H

#include <QtGui>
#include <QWidget>
#include <QTabWidget>
#include "PageInsideTab.h"

namespace Ui {
class ChatWindow;
}

class ChatWindow : public QWidget
{
Q_OBJECT

public:
explicit ChatWindow(QWidget *parent = 0);
~ChatWindow();
void closeEvent();
QVBoxLayout *mainLayout;
QTabWidget *tabWidget;
QLabel *lbl_Message;
QLineEdit *lineEdit_TextInput;
QList <PageInsideTab *> pageList;


private:
Ui::ChatWindow *ui;

public slots:
void init();
void returnPressed();
void appendMessage(const QString &from, const QString &message);
void setBuddyName(QString);
void createNewTab(QString buddyName);
void historyButtonClicked();
void createPageList();
};

#endif // CHATWINDOW_H


and part of the cpp file:


void ChatWindow :: init()
{
mainLayout = new QVBoxLayout();
setLayout(mainLayout);
tabWidget = new QTabWidget();
tabWidget->setMinimumSize(200,150);
lbl_Message = new QLabel();
lbl_Message->setText("Message:");
lineEdit_TextInput = new QLineEdit();
mainLayout->addWidget(tabWidget);
mainLayout->addWidget(lbl_Message);
mainLayout->addWidget(lineEdit_TextInput);
tabWidget->show();
lbl_Message->show();
lineEdit_TextInput->show();
}

void ChatWindow :: createPageList()
{
PageInsideTab *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13, *p14, *p15;
pageList.append(p1);
pageList.append(p2);
pageList.append(p3);
pageList.append(p4);
pageList.append(p5);
pageList.append(p6);
pageList.append(p7);
pageList.append(p8);
pageList.append(p9);
pageList.append(p10);
pageList.append(p11);
pageList.append(p12);
pageList.append(p13);
pageList.append(p14);
pageList.append(p15);
}

void ChatWindow :: createNewTab(QString buddyName)
{
static int tabIndex;
PageInsideTab *ptr;
// ptr = pageList.at(tabIndex);
ptr = new PageInsideTab(tabWidget);
//qDebug()<<"tabIndex="<<tabIndex;
tabWidget->insertTab(tabIndex, ptr, buddyName);
// tabWidget->addTab(ptr, buddyName);
tabIndex++;
}


init() and createPageList() i'm calling in the constructor of this class(ChatWindow), and creatNewTab(QString) is
called from another class supplying the parameter buddyName. This time I've commented the use of pageList pointers
but in this case also, I'm getting SEGMENTATION fault in the SECOND run of the slot creatNewTab(QString). :(

amleto
24th December 2011, 13:20
this is ridiculous


void ChatWindow :: createPageList()
{
PageInsideTab *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10, *p11, *p12, *p13, *p14, *p15;
pageList.append(p1);
pageList.append(p2);
pageList.append(p3);
pageList.append(p4);
pageList.append(p5);
pageList.append(p6);
pageList.append(p7);
pageList.append(p8);
pageList.append(p9);
pageList.append(p10);
pageList.append(p11);
pageList.append(p12);
pageList.append(p13);
pageList.append(p14);
pageList.append(p15);
}


no doubt somewhere you are using one of the many uninitialised pointers here. DO NOT add meaningless pointers to your pageList.

If you commented all use of pagelist, why did you show a function that ONLY uses pagelist?

Warning:


static int x;
++x;

You might get away with that, but you wont get away with


int x;
++x;


Another major point, if you know where it is segfaulting, why aren't you getting the debugger out and looking at some variables? Learning how to debug is not optional for programmers.