PDA

View Full Version : Newbie Help - Signals/Slots between dialog and widgets



progman
21st March 2011, 01:02
Hello,

I have a dialog which contains one QTabWidget consisting of several tabs. Each tab has its own class and I am adding a calculate button to each tab page. But when the user selects calculate, nothing happens. For now, I have a test message box that should indicate that the button was pressed, but it never hits the function, which debug confirms. The class of the widget is as follows:



class AcreTab : public QWidget
{
Q_OBJECT

public:
AcreTab(QWidget *parent=0);
QPushButton *pbAcreCalc;

};


and the dialog class is as follows:



class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog(QWidget *parent = 0);
~Dialog();

private slots:
void AcreCalc();

private:
QTabWidget *tabWidget;

};


The signal/slot mechanism as well as tab setup is as follows:



Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
// Setup the tabs...

tabWidget = new QTabWidget();
tabWidget->addTab(new AcreTab, tr("Acre"));
tabWidget->addTab(new acresTab, tr("acres"));
tabWidget->addTab(new amperesTab, tr("amperes"));
tabWidget->addTab(new ampereHrsTab, tr("ampere-hours"));
tabWidget->addTab(new ampereTurnsTab, tr("ampere-turns"));
tabWidget->addTab(new atmosTab, tr("atmospheres"));
tabWidget->addTab(new oilBarrel, tr("barrel, oil"));
tabWidget->addTab(new barTab, tr("bars"));
tabWidget->addTab(new btuTab, tr("btu"));
tabWidget->addTab(new btuHrsTab, tr("btu/hrs"));
tabWidget->addTab(new btuMinTab, tr("btu/min"));
tabWidget->addTab(new bushelsTab, tr("bushels"));
tabWidget->addTab(new cmTab, tr("centimetres"));
tabWidget->addTab(new cmDynesTab, tr("centimetre-dynes"));
tabWidget->addTab(new cmGramsTab, tr("centimetre-grams"));
tabWidget->addTab(new cmMercTab, tr("centimetre-grams"));
tabWidget->addTab(new cmSecTab, tr("centimetre-sec"));
tabWidget->addTab(new cmCubeTab, tr("cubic centimetres"));
tabWidget->addTab(new cubicFtTab, tr("cubic feet"));
tabWidget->addTab(new cubicFtMinTab, tr("cubic feet/min"));
tabWidget->addTab(new cubicInchesTab, tr("cubic inches"));
tabWidget->addTab(new cubicMetresTab, tr("cubic metres"));

AcreTab acrTb;
connect(acrTb.pbAcreCalc, SIGNAL(clicked()),this, SLOT(AcreCalc()));


//Layout the dialog box...

QVBoxLayout *mLayout = new QVBoxLayout;
mLayout->addWidget(tabWidget);
setLayout(mLayout);

}



And the tabs are created by:



AcreTab::AcreTab(QWidget *parent)
: QWidget(parent)
{

QLabel *lblConvertFrom = new QLabel(tr("Convert From: "));
QLineEdit *leConvFrom = new QLineEdit();
QLabel *lblConvertTo = new QLabel(tr("Convert To: "));
QLineEdit *leConvTo = new QLineEdit();

QLabel *lblAcreConv = new QLabel(tr("Answer: "));
lblAcreConv->setAlignment(Qt::AlignRight);
QLineEdit *leAcreAns = new QLineEdit();
pbAcreCalc = new QPushButton("&Convert",this);

QComboBox *cbAcreF = new QComboBox;
cbAcreF->addItem(tr("Acres"));
cbAcreF->addItem(tr("Sq. Chain, Gunters"));
cbAcreF->addItem(tr("Rods"));
cbAcreF->addItem(tr("Sq. Links, Gunters"));
cbAcreF->addItem(tr("Hectare"));

QComboBox *cbAcreT = new QComboBox;
cbAcreT->addItem(tr("Acres"));
cbAcreT->addItem(tr("Sq. Chain, Gunters"));
cbAcreT->addItem(tr("Rods"));
cbAcreT->addItem(tr("Sq. Links, Gunters"));
cbAcreT->addItem(tr("Hectare"));

QGridLayout *mLayout = new QGridLayout;
mLayout->addWidget(lblConvertFrom,0,0);
mLayout->addWidget(leConvFrom,0,1);
mLayout->addWidget(cbAcreF,0,2);
mLayout->addWidget(lblConvertTo,1,0);
mLayout->addWidget(leConvTo,1,1);
mLayout->addWidget(cbAcreT,1,2);
mLayout->addWidget(pbAcreCalc, 2,0);
mLayout->addWidget(lblAcreConv, 2,1);
mLayout->addWidget(leAcreAns, 2,2);
setLayout(mLayout);
}


It compiles with no warnings and runs with no 'object not found' indicators in the run window. All the funtionality relating to tabs, selecting items in combo boxes, etc, work, just nothing happens when the button is pushed from inside the tabbed page. Basically, the program will be a unit conversion program, which allows the user to input one value, and have the conversion done for them. The button is used to take the user input and return a value to them. The button passes back the message to the dialog, which then calls the applicable conversion function to return the converted number back to the user, and show the user the converted number within the tab page.

Can all this be done within the tab page, that is, get the user input, convert it, then show it back to the user, once the user presses the convert button? Or does the main dialog need to handle the conversion, like I'm trying too now?

I'm new to Qt so not 100% sure of signals/slots, but how do you pass the signal from the tab page to the dialog app?

Thanks!

ChrisW67
21st March 2011, 02:01
This is a C++ issue. acrTb, created at line 30 in your dialog constructor listing above ceases to exist at the end of the constructor and this severs any connections made to/from it. You need to allocate it on the heap. It seems you do that at line 7, and it is that instance that you should connect.

progman
21st March 2011, 02:45
Yes, I'm beginning to see that myself, just not sure how to reconcile the code to clean up the mess I've made.....

norobro
21st March 2011, 03:09
Can all this be done within the tab page, ...Yes. Put the slot in your AcreTab class and the connect statement in the AcreTab constructor.

Question: If you're converting from one unit of measure to another why three QLineEdits?

progman
21st March 2011, 03:38
Yes. Put the slot in your AcreTab class and the connect statement in the AcreTab constructor.

Question: If you're converting from one unit of measure to another why three QLineEdits?

Yes, I realized that too after I posted and it has been fixed.... :)

Added after 13 minutes:


Yes. Put the slot in your AcreTab class and the connect statement in the AcreTab constructor.

Question: If you're converting from one unit of measure to another why three QLineEdits?

Putting everything into the AcreTab worked perfectly! Thanks!