You are not logged in.
Thanks for your tips. I'd like to try option #1... so I've got this now,
//run sendEmail() when item8 is clicked
QObject::connect(item8, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(item8, item3);
QObject::connect(signalMapper, SIGNAL(mapped(QString)), composerInstance, SLOT(sendEmail(QString)));
What are you saying exactly about the last line there?
Offline
change it to
QObject::connect(signalMapper, SIGNAL(mapped(QWidget*)), composerInstance, SLOT(sendEmail(QWidget*)));
then in sendEmail do something like:
void sendEmail(QWidget *textBox) {
QLineEdit *lineEdit = qobject_cast<QLineEdit*>(textBox);
QString address = (lineEdit)? lineEdit->text() : "";
QString printOut = QString("echo \"sending email to %1\"").arg(address);
system(printOut.toUtf8());
}
I did not have time to test this, but I think it will work.
Offline
Thanks! That works, although, unfortunately I do not see how I can pass more than one QWidget to sendEmail()... Is there a way? It seems setMapping will only let me map one QWidget at a time...
Offline
QSignalMapper also lets you create mappings for QObjects, so just create a class that is a QObject with public pointers to all the widgets you want to reference. Again, not the most elegant, but it should get the job done. I always prefer get it working first, then make it pretty.
Some pseudo-code since that might be easier to understand...
class WidgetContainer : public QObject {
public:
WidgetContainer(QWidget *thingOne, QWidget *thingTwo, QWidget *thingThree, QObject *parent = NULL)
:QObject(parent),
firstThing(thingOne),
secondThing(thingTwo),
thirdThing(thingThree)
{
}
QWidget1 *firstThing;
QWidget2 *secondThing;
QWidget3 *thirdThing;
}
signalMapper->setMapping(item8, myWidgetContainer);
QObject::connect(signalMapper, SIGNAL(mapped(QObject*)), composerInstance, SLOT(sendEmail(QObject*)));
void sendEmail(QObject *container) {
WidgetContainer *widgetContainer = qobject_cast<WidgetContainer*>(container);
if(widgetContainer) {
// Do the old sendEmail stuff in here pulling from widgetContainer->firstThing, secondThing, thirdThing etc. when needed.
}
I realize now that is more C++ than pseudo-code :-P
Offline
I see the second code section goes in main.cpp and the third goes in emailcomposer.h. Where does the first go? I have tried it in emailcomposer.h, but without luck,
#ifndef EMAILCOMPOSER_H
#define EMAILCOMPOSER_H
#include <QtGui>
#include <cstdlib>
class EmailComposer : public QObject {
Q_OBJECT
public:
EmailComposer() {}
public slots:
void sendEmail(QWidget *textBox) {
QTextEdit *textEdit = qobject_cast<QTextEdit*>(textBox);
system(QString("echo \"sending email to %1\"").arg((textEdit)? (textEdit)->toPlainText() : "").toUtf8());
}
};
class WidgetContainer : public QObject {
Q_OBJECT
public:
WidgetContainer(QWidget *thingOne, QWidget *thingTwo, QObject *parent = NULL) : QObject(parent), QLineEdit(thingOne), QTextEdit(thingTwo) {
QLineEdit *firstThing;
QTextEdit *secondThing;
}
};
#endif
Here is the error I get when I try to compile:
./emailcomposer.h: In constructor 'WidgetContainer::WidgetContainer(QWidget*, QWidget*, QObject*)':
./emailcomposer.h:24: error: type 'QLineEdit' is not a direct base of 'WidgetContainer'
./emailcomposer.h:24: error: type 'QTextEdit' is not a direct base of 'WidgetContainer'
Offline
Double check your code, it looks like you didn't copy the WidgetContainer class correctly. Specifically your initializer list.
Offline
Yeah; I was a little unsure about the proper usage of that code. I think I am doing it closer to correct now, but I am still having an issue. It seems I cannot make a widget container inside the header file because the definition of the widget container is also in that header file...
emailcomposer.h,
#ifndef EMAILCOMPOSER_H
#define EMAILCOMPOSER_H
#include <QtGui>
#include <cstdlib>
class EmailComposer : public QObject {
Q_OBJECT
public:
EmailComposer() {}
public slots:
void sendEmail(QObject *container) {
WidgetContainer *widgetContainer = qobject_cast<WidgetContainer*>(container);
if (widgetContainer) {
QTextEdit *textEdit = qobject_cast<QTextEdit*>(widgetContainer->firstThing());
system(QString("echo \"sending email to %1\"").arg((textEdit)? (textEdit)->toPlainText() : "").toUtf8());
}
}
};
class WidgetContainer : public QObject {
Q_OBJECT
public:
WidgetContainer(QWidget *thingOne, QWidget *thingTwo, QObject *parent = NULL)
:QObject(parent),
firstThing(thingOne),
secondThing(thingTwo)
{
}
QWidget *firstThing;
QWidget *secondThing;
};
#endif
main.cpp,
#include <QtGui>
#include <emailcomposer.h>
int main(int argc, char *argv[]) {
//define qapplication class
QApplication app(argc, argv);
//create an instance of the email composer
EmailComposer *composerInstance = new EmailComposer;
//create qt widgets and signal mappers
QWidget *window = new QWidget;
QSignalMapper *signalMapper = new QSignalMapper(window);
QLabel *item1 = new QLabel("Status: ready...");
QLabel *item2 = new QLabel("Name:");
QLineEdit *item3 = new QLineEdit("put the name here!");
QLabel *item4 = new QLabel("Options:");
QComboBox *item5 = new QComboBox();
item5->insertItem(0, "a");
item5->insertItem(1, "b");
item5->insertItem(2, "c");
QLabel *item6 = new QLabel("begin!");
QTextEdit *item7 = new QTextEdit();
QPushButton *item8 = new QPushButton("Send");
//create WidgetContainer
WidgetContainer *myWidgetContainer = new WidgetContainer(item3, item7);
//run sendEmail() when item8 is clicked
QObject::connect(item8, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(item8, myWidgetContainer);
QObject::connect(signalMapper, SIGNAL(mapped(QObject*)), composerInstance, SLOT(sendEmail(QObject*)));
//create layout and add widgets to layout
QGridLayout *layout = new QGridLayout;
layout->addWidget(item1, 0, 0, 1, 2);
layout->addWidget(item2, 2, 0);
layout->addWidget(item3, 2, 1);
layout->addWidget(item4, 3, 0);
layout->addWidget(item5, 3, 1);
layout->addWidget(item6, 4, 0, 1, 2);
layout->addWidget(item7, 5, 0, 1, 2);
layout->addWidget(item8, 6, 0, 1, 2);
//output to screen
window->setLayout(layout);
window->show();
//pass control to qt
return app.exec();
}
The error,
[karam@boris emailcomposer]$ qmake -project
[karam@boris emailcomposer]$ qmake
[karam@boris emailcomposer]$ make
g++ -c -m64 -pipe -march=x86-64 -mtune=generic -O2 -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt/mkspecs/linux-g++-64 -I. -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include -I. -I. -I. -I. -o main.o main.cpp
In file included from main.cpp:2:
./emailcomposer.h: In member function 'void EmailComposer::sendEmail(QObject*)':
./emailcomposer.h:15: error: 'WidgetContainer' was not declared in this scope
./emailcomposer.h:15: error: 'widgetContainer' was not declared in this scope
./emailcomposer.h:15: error: 'WidgetContainer' cannot appear in a constant-expression
./emailcomposer.h:15: error: parse error in template argument list
./emailcomposer.h:15: error: no matching function for call to 'qobject_cast(QObject*&)'
make: *** [main.o] Error 1
[karam@boris emailcomposer]$
Offline
Try this:
emailcomposer.h
#ifndef EMAILCOMPOSER_H
#define EMAILCOMPOSER_H
#include <QtGui>
#include <cstdlib>
class WidgetContainer : public QObject {
Q_OBJECT
public:
WidgetContainer(QWidget *thingOne, QWidget *thingTwo, QObject *parent = NULL)
:QObject(parent),
firstThing(thingOne),
secondThing(thingTwo)
{
}
QWidget *firstThing;
QWidget *secondThing;
};
class EmailComposer : public QObject {
Q_OBJECT
public:
EmailComposer() {}
public slots:
void sendEmail(QObject *container) {
WidgetContainer *widgetContainer = qobject_cast<WidgetContainer*>(container);
if (widgetContainer) {
QTextEdit *textEdit = qobject_cast<QTextEdit*>(widgetContainer->firstThing());
system(QString("echo \"sending email to %1\"").arg((textEdit)? (textEdit)->toPlainText() : "").toUtf8());
}
}
};
#endif
Offline
scio: It works perfectly now! I have one last question for you: this little piece of code is actually part of an open-source package I'm planning to release next month and I'd like to put you somewhere in the credits. Shall I refer to you as simply 'scio' or is there a full name you'd like to give me? Thanks again for all your help!
Offline
Adam Weiss is my name, thanks.
Offline
The code has been released: http://krondi.org
Offline