PDA

View Full Version : Suggestion for Multiple Page Widget.



SiddhantR
12th July 2013, 10:29
I have a multiple page widget with a layout like the pic shown.
I have a top level 8 buttons (A,B,C...)). On clicking any one button a subpage appears. Now this page has 12 pages which are to change based on the side functional 12 buttons ( 6 on each side).

I wanted to know which is the best solution from the following three.
1. Having a mdiarea with 8 subwindows for top 8 buttons and each subwindow having a QStackedWidget for the side buttons.
2. A QTabWidget with a QStackedWidget for each subpage.
3. A QStackedWidget having 8 pages of top buttons and further everypage of this stackedwidget will have another QStackedWidget for the side buttons.


9282

Thank You :)

Santosh Reddy
12th July 2013, 11:31
If everything is a button (ie. 8+12 buttons = 20) and all the 20 buttons do not change from page to page (i.e. for all 8*12 = 96 pages) then I will recommend to use QGridLayout,
adjust the layout as per requirements and let the pages be displayed using QStackedWidget (the central one). Make and brake signal and slot connections of vertical buttons s dynamically when the top buttons are clicked.

SiddhantR
12th July 2013, 12:55
Thanks for the reply.
Do you mean to say that Stacked Widget should contain all the 96 pages and the stcked widget is placed on a grid layout. If I do this what will be the advantage of using a Grid layout?

Santosh Reddy
12th July 2013, 12:57
If I do this what will be the advantage of using a Grid layout?
You can layout the top, left and right buttons around the stacked widget.

SiddhantR
12th July 2013, 13:42
But by having all the 96 pages in a single stacked widget the coding will increase right. As of now I have to write just 8+12 lines of code for setting current index and if I use single stacked widget I will have to have a function in which a top button will relate to fixed index limit according to the requirement.

Santosh Reddy
12th July 2013, 14:29
It should not be a big thing, here is an working exmaple of what you are looking for. This what I suggested and mapping of buttons and the widgets is done using QSignalMapper


class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget * parent = 0)
: QWidget(parent)
, mStackedWidget(new QStackedWidget)
, mHPushButtons()
, mVPushButtons()
, mGridLayout(new QGridLayout(this))
, mActivePage(0)
, mActiveWidget()
{
// Create Horizontal QPushButton 8 Qty
for(int i = 0; i < HButtons; i++)
{
mHPushButtons[i] = new QPushButton(QString("Page %1").arg(i + 1));
mActiveWidget[i] = 0;
}

// Create Vertical QPushButton 6 * 2 = 12 Qty
for(int i = 0; i < LButtons + RButtons; i++)
mVPushButtons[i] = new QPushButton(QString("Widget %1").arg(i + 1));

QSignalMapper * pageSignalMapper = new QSignalMapper(this);
connect(pageSignalMapper, SIGNAL(mapped(int)), SLOT(hButtonClicked(int)));

QSignalMapper * widgetSignalMapper = new QSignalMapper(this);
connect(widgetSignalMapper, SIGNAL(mapped(int)), SLOT(vButtonClicked(int)));


// Create Page Widgets - 8 * 12 = 96 Qty
for(int i = 0; i < HButtons; i++)
{
connect(mHPushButtons[i], SIGNAL(clicked()), pageSignalMapper, SLOT(map()));
pageSignalMapper->setMapping(mHPushButtons[i], i);

for(int j = 0; j < LButtons + RButtons; j++)
{
QLabel * label = new QLabel(QString("QWidget : Page %1, Widget %2").arg(i + 1).arg(j + 1));
mStackedWidget->addWidget(label);

connect(mVPushButtons[j], SIGNAL(clicked()), widgetSignalMapper, SLOT(map()));
widgetSignalMapper->setMapping(mVPushButtons[j], j);
}
}

// Add Horozontal QPushButtons to QGridLayout
for(int i = 0; i < HButtons; i++)
mGridLayout->addWidget(mHPushButtons[i], 0, i, 1, 1);

// Add Left Vertical QPushButtons to QGridLayout
for(int i = 0; i < LButtons; i++)
mGridLayout->addWidget(mVPushButtons[i], 1 + i, 0, 1, 1);

// Add Vertical QPushButtons to QGridLayout
for(int i = LButtons; i < LButtons + RButtons; i++)
mGridLayout->addWidget(mVPushButtons[i], 1 + i - LButtons, HButtons - 1, 1, 1);

// Add QStackedWidget to QGridLayout
mGridLayout->addWidget(mStackedWidget, 1, 1, LButtons, HButtons - 2);
}

private slots:
void hButtonClicked(int page)
{
mActivePage = page;
activateWidget();
}

void vButtonClicked(int widget)
{
mActiveWidget[mActivePage] = widget;
activateWidget();
}

private:
static const int HButtons = 8;
static const int LButtons = 6;
static const int RButtons = 6;

QStackedWidget * mStackedWidget;
QPushButton * mHPushButtons[HButtons];
QPushButton * mVPushButtons[LButtons + RButtons];
QGridLayout * mGridLayout;

int mActivePage;
int mActiveWidget[HButtons];


void activateWidget(void)
{
int index = mActivePage * (LButtons + RButtons) + mActiveWidget[mActivePage];
mStackedWidget->setCurrentIndex(index);
}
};

SiddhantR
15th July 2013, 08:10
Hey thanks a ton for your help. This works really well... :) :)

SiddhantR
16th July 2013, 06:12
Hey I have one more problem. Below the buttons there are labels which change color on button click. I am not able to align them exactly below the buttons. I have tried playing with layouts but nothing is helping. Actually the buttons will go once I integrate it with my actual hardware and hence I cant keep them in a layout with the buttons. Can you please suggest something here.
Thanks.

Santosh Reddy
16th July 2013, 06:23
As you say buttons will to go away, then why not put the labels in place of buttons?

SiddhantR
16th July 2013, 06:31
There are labels jus below buttons. But their size is fixed and to try now we need the buttons. The buttons will go away when we integrate that is still another 3 4 months away... :)

Santosh Reddy
16th July 2013, 07:37
Can you show me what you want and what you get?

SiddhantR
31st July 2013, 09:39
Hiii,
The code that you gave for multiple widgets is working fine. Today I found that when the index is set the loop gets executed 8 times. It is causing problem when I integrate business logic on the button click. That code also gets executed 8 times which is causing problem. Can you please guide on this as to why am I facing this problem?
I added a QMessageBox in actvateWidget() after setCurrentIndex and it gets executed 8 times if I click any of the functional buttons. I have written the code constructor of main window.
Thank you.

Santosh Reddy
1st August 2013, 08:37
Here you go, the problem was with the signal mapper connections, it was being created multiple (8) time.


class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget * parent = 0)
: QWidget(parent)
, mStackedWidget(new QStackedWidget)
, mHPushButtons()
, mVPushButtons()
, mGridLayout(new QGridLayout(this))
, mActivePage(0)
, mActiveWidget()
{
// Create Horizontal QPushButton 8 Qty
for(int i = 0; i < HButtons; i++)
{
mHPushButtons[i] = new QPushButton(QString("Page %1").arg(i + 1));
mActiveWidget[i] = 0;
}

// Create Vertical QPushButton 6 * 2 = 12 Qty
for(int i = 0; i < LButtons + RButtons; i++)
mVPushButtons[i] = new QPushButton(QString("Widget %1").arg(i + 1));

QSignalMapper * pageSignalMapper = new QSignalMapper(this);
connect(pageSignalMapper, SIGNAL(mapped(int)), SLOT(hButtonClicked(int)));

QSignalMapper * widgetSignalMapper = new QSignalMapper(this);
connect(widgetSignalMapper, SIGNAL(mapped(int)), SLOT(vButtonClicked(int)));

// Create Page Widgets - 8 * 12 = 96 Qty
for(int i = 0; i < HButtons; i++)
{
connect(mHPushButtons[i], SIGNAL(clicked()), pageSignalMapper, SLOT(map()));
pageSignalMapper->setMapping(mHPushButtons[i], i);

for(int j = 0; j < LButtons + RButtons; j++)
{
QLabel * label = new QLabel(QString("QWidget : Page %1, Widget %2").arg(i + 1).arg(j + 1));
mStackedWidget->addWidget(label);
}
}

for(int j = 0; j < LButtons + RButtons; j++)
{
connect(mVPushButtons[j], SIGNAL(clicked()), widgetSignalMapper, SLOT(map()));
widgetSignalMapper->setMapping(mVPushButtons[j], j);
}

// Add Horozontal QPushButtons to QGridLayout
for(int i = 0; i < HButtons; i++)
mGridLayout->addWidget(mHPushButtons[i], 0, i, 1, 1);

// Add Left Vertical QPushButtons to QGridLayout
for(int i = 0; i < LButtons; i++)
mGridLayout->addWidget(mVPushButtons[i], 1 + i, 0, 1, 1);

// Add Vertical QPushButtons to QGridLayout
for(int i = LButtons; i < LButtons + RButtons; i++)
mGridLayout->addWidget(mVPushButtons[i], 1 + i - LButtons, HButtons - 1, 1, 1);

// Add QStackedWidget to QGridLayout
mGridLayout->addWidget(mStackedWidget, 1, 1, LButtons, HButtons - 2);
}

private slots:
void hButtonClicked(int page)
{
mActivePage = page;
activateWidget();
}

void vButtonClicked(int widget)
{
mActiveWidget[mActivePage] = widget;
activateWidget();
}

private:
static const int HButtons = 8;
static const int LButtons = 6;
static const int RButtons = 6;

QStackedWidget * mStackedWidget;
QPushButton * mHPushButtons[HButtons];
QPushButton * mVPushButtons[LButtons + RButtons];
QGridLayout * mGridLayout;

int mActivePage;
int mActiveWidget[HButtons];


void activateWidget(void)
{
int index = mActivePage * (LButtons + RButtons) + mActiveWidget[mActivePage];
mStackedWidget->setCurrentIndex(index);
}
};

SiddhantR
1st August 2013, 10:13
Thanks a lot...