View Full Version : custom slot/signal
awnjoor
16th July 2006, 13:10
Hi Im new here and Id like to ask a few questions please,
In my program there is a QLineEdit and a QLabel. What I want to do is when the user enter something in the LineEdit, I want to do some processing with it then displaying the result in QLabel. I was thinking of something like
connect(lineEdit, SIGNAL(returnPressed()), qLabel, SLOT(setText("asdf")))
but after some reading i found out that you cannot pass values in connect and besides with the above code i cannot process the input from lineedit. I read the documentation about signals and slots and I understood it somehow but I just didnt understand it enough to write my own slot/signal.
so can somebody please help me to understand and write my own slot/signal. thank you.
Let's say you have a main window containing those widgets. Then the code could look something like this:
header:
...
class MainWindow: public QMainWindow
{
Q_OBJECT // <- this macro is important
public:
MainWindow(...);
~MainWindow();
...
// your own custom slot declaration looks like this:
private slots:
void processInput();
};
implementation:
MainWindow::MainWindow(...) : ...
{
// connection between line edit and your custom slot
connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(processInput()));
}
// custom slot implementation
void MainWindow::processInput()
{
// process the line edit text
QString text = process(lineEdit->text());
// set the result
qLabel->setText(text);
}
awnjoor
16th July 2006, 14:33
thank you for the speedy reply, now here is the code
#include<QApplication>
#include<QLabel>
#include<QLineEdit>
#include<QString>
class myWidget:public QWidget{
Q_OBJECT
public:
myWidget(QWidget *parent=0);
private slots:
void processInput();
};
myWidget::myWidget(QWidget *parent)
:QWidget(parent)
{
QLabel *display=new QLabel(this);
QLineEdit *lineEdit=new QLineEdit;
connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(processInput()));
}
void myWidget::processInput(){
QString text=lineEdit->text();
display->setText(text);
}
int main(int argc, char **argv){
QApplication app(argc, argv);
myWidget window;
window.show();
return app.exec();
}
and i got undeclared error of lineEdit and display
jacek
16th July 2006, 14:55
The problem is that you declare lineEdit as a local variable in the constructor. If you want to access it in a different method, you have to declare it as a member variable.
aMan
16th July 2006, 14:57
you have declared the objects in the constructor, so they are available only there.
you should do something like that
class myWidget:public QWidget{
Q_OBJECT
public:
myWidget(QWidget *parent=0);
private slots:
void processInput();
private:
QLabel display;
QLineEdit lineEdit;
};
awnjoor
16th July 2006, 15:11
now i got new error, undefined reference to vtable for myWidget
#include<QApplication>
#include<QLabel>
#include<QLineEdit>
#include<QString>
class myWidget:public QWidget{
Q_OBJECT
public:
myWidget(QWidget *parent=0);
private slots:
void processInput();
private:
QLabel *display;
QLineEdit *lineEdit;
};
myWidget::myWidget(QWidget *parent)
:QWidget(parent)
{
display=new QLabel;
lineEdit=new QLineEdit;
connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(processInput()));
}
void myWidget::processInput(){
QString text=lineEdit->text();
display->setText(text);
}
int main(int argc, char **argv){
QApplication app(argc, argv);
myWidget window;
window.show();
return app.exec();
}
Try adding line:
#include "main.moc"
somewhere in your main.cpp.
You will have to include the moc file by hand in case you don't have separate class header files.
awnjoor
16th July 2006, 22:48
so i just add the include line to main.cpp right? i did that but the compiler said that there is no such file or directory :confused:
jacek
16th July 2006, 23:09
i did that but the compiler said that there is no such file or directory
How do you compile your application?
awnjoor
17th July 2006, 00:09
kay, i deleted everything in the folder, except main.cpp. Then i did qmake -project then qmake and then make. Now the error is in the moc file
here is my moc file
/************************************************** **************************
** Meta object code from reading C++ file 'main.cpp'
**
** Created: Mon Jul 17 06:56:41 2006
** by: The Qt Meta Object Compiler version 59 (Qt 4.1.4)
**
** WARNING! All changes made in this file will be lost!
************************************************** ***************************/
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'main.cpp' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 59
#error "This file was generated using the moc from 4.1.4. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
static const uint qt_meta_data_myWidget[] = {
// content:
1, // revision
0, // classname
0, 0, // classinfo
1, 10, // methods
0, 0, // properties
0, 0, // enums/sets
// slots: signature, parameters, type, tag, flags
10, 9, 9, 9, 0x08,
0 // eod
};
static const char qt_meta_stringdata_myWidget[] = {
"myWidget\0\0processInput()\0"
};
const QMetaObject myWidget::staticMetaObject = {
{ &QWidget::staticMetaObject, qt_meta_stringdata_myWidget,
qt_meta_data_myWidget, 0 }
};
const QMetaObject *myWidget::metaObject() const
{
return &staticMetaObject;
}
void *myWidget::qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, qt_meta_stringdata_myWidget))
return static_cast<void*>(const_cast<myWidget*>(this));
return QWidget::qt_metacast(_clname);
}
int myWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
switch (_id) {
case 0: processInput(); break;
}
_id -= 1;
}
return _id;
}
i dont know how to output the errors to a file so here is the image
http://us.share.geocities.com/dymlg/1.bmp
jacek
17th July 2006, 01:02
kay, i deleted everything in the folder, except main.cpp. Then i did qmake -project then qmake and then make.
Then it should work, unless your project is located in "qt" directory (in such case you must add "TARGET += something" to your .pro file).
Now the error is in the moc file
All moc files correct. The error must be in some other place.
i dont know how to output the errors to a file so here is the image
Just cut & paste them. If you are using windows console, you can find cut & paste tools after you left-click the icon in the top-left corner of the window.
http://us.share.geocities.com/dymlg/1.bmp
"This page is not available."
You can post images here --- just click "Manage Attachements" button below the editor, but please don't post BMPs (even MS Paint can save images as PNGs or GIFs).
awnjoor
17th July 2006, 01:28
>>Then it should work, unless your project is located in "qt" directory (in such case you must add "TARGET += something" to your .pro file)
no, my project is not located in qt directory.
here is the error
In file included from main.cpp:6:
release/main.moc:38: error: `myWidget' has not been declared
release/main.moc:43: error: `myWidget' has not been declared
release/main.moc:44: error: non-member function `const QMetaObject* metaObject()
' cannot have `const' method qualifier
release/main.moc:48: error: `myWidget' has not been declared
release/main.moc: In function `void* qt_metacast(const char*)':
release/main.moc:52: error: `myWidget' has not been declared
release/main.moc:52: error: expected `>' before '*' token
release/main.moc:52: error: expected `(' before '*' token
release/main.moc:52: error: expected primary-expression before '>' token
release/main.moc:52: error: invalid use of `this' in non-member function
release/main.moc:52: error: expected `)' before ';' token
release/main.moc:53: error: cannot call member function `virtual void* QWidget::
qt_metacast(const char*)' without object
release/main.moc: At global scope:
release/main.moc:56: error: `myWidget' has not been declared
release/main.moc: In function `int qt_metacall(QMetaObject::Call, int, void**)':
release/main.moc:58: error: cannot call member function `virtual int QWidget::qt
_metacall(QMetaObject::Call, int, void**)' without object
release/main.moc:63: error: `processInput' undeclared (first use this function)
release/main.moc:63: error: (Each undeclared identifier is reported only once fo
r each function it appears in.)
mingw32-make[1]: *** [release\main.o] Error 1
mingw32-make[1]: Leaving directory `C:/Thesis/temp'
mingw32-make: *** [release-all] Error 2
jacek
17th July 2006, 01:38
In file included from main.cpp:6:
Move #include "main.moc" directive to the end of file.
awnjoor
17th July 2006, 01:48
::bows down::
thank you all. now jacek would you care to explain why i have to move the moc directive down
jacek
17th July 2006, 01:56
why i have to move the moc directive down
Because main.moc contains implementation of myWidget methods (which were added by Q_OBJECT macro) and in C++ you have to place method implementation after corresponding class definition.
awnjoor
17th July 2006, 02:39
sigh, im trying to do the custom slot/signal again but it is not working. here is the code
#include<QTableWidgetItem>
#include<QApplication>
#include<QWidget>
#include<QPushButton>
#include<QLabel>
#include<QFont>
#include<QLineEdit>
#include<QTableWidget>
#include<QVBoxLayout>
#include<QHBoxLayout>
#include<QStringList>
#include<QtSql/QSqlDatabase>
#include<QtSql/QSqlQuery>
#include<QString>
#include<QObject>
class myWidget:public QWidget{
Q_OBJECT
public:
myWidget(QWidget *parent=0);
private slots:
void processInput();
private:
QLabel *displayItem;
QLineEdit *itemnumber;
};
myWidget::myWidget(QWidget *parent)
:QWidget(parent)
{
setWindowState(Qt::WindowFullScreen);
QLabel *title = new QLabel;
title->setFont(QFont("Verdana", 30, 0));
title->setText("title");
title->setAlignment(Qt::AlignHCenter);
QLabel *item=new QLabel;
item->setFont(QFont("verdana", 15, QFont::Bold));
item->setText("Item");
displayItem=new QLabel;
//displayItem->setFont(QFont("verdana", 15, QFont::Bold));
//displayItem->setText("asdf");
itemnumber=new QLineEdit;
itemnumber->setMaxLength(10);
QLabel *quantity=new QLabel;
quantity->setFont(QFont("verdana", 15, QFont::Bold));
quantity->setText("Quantity");
QLineEdit *quantitynumber=new QLineEdit;
quantitynumber->setMaxLength(10);
QStringList columnLabels;
columnLabels << "Item" << "#" << "TOTAL";
QTableWidget *tableWidget=new QTableWidget;
tableWidget->setRowCount(1);
tableWidget->setColumnCount(3);
tableWidget->setHorizontalHeaderLabels(columnLabels);
tableWidget->setColumnWidth(0, 250);
tableWidget->setColumnWidth(1, 30);
tableWidget->setColumnWidth(2, 100);
QHBoxLayout *hLeft1=new QHBoxLayout;
hLeft1->addWidget(item);
hLeft1->addWidget(itemnumber);
QHBoxLayout *hLeft2=new QHBoxLayout;
hLeft1->addWidget(quantity);
hLeft1->addWidget(quantitynumber);
QVBoxLayout *vLeft=new QVBoxLayout;
vLeft->addLayout(hLeft1);
vLeft->addLayout(hLeft2);
QHBoxLayout *hLeft=new QHBoxLayout;
hLeft->addLayout(vLeft);
hLeft->addStretch(0);
QVBoxLayout *mainLeft=new QVBoxLayout;
mainLeft->addWidget(displayItem);
mainLeft->addStretch(0);
mainLeft->addLayout(hLeft);
mainLeft->addStretch(0);
QHBoxLayout *mainBottom=new QHBoxLayout;
mainBottom->addLayout(mainLeft);
mainBottom->addWidget(tableWidget);
QVBoxLayout *mainLayout=new QVBoxLayout(this);
mainLayout->addWidget(title);
mainLayout->addSpacing(80);
mainLayout->addLayout(mainBottom);
setLayout(mainLayout);
itemnumber->setFocus();
//itemnumber->setText("asdf");
connect(itemnumber, SIGNAL(returnPressed()), this, SIGNAL(processInput()));
}
void myWidget::processInput(){
//QString text=itemnumber->text();
itemnumber->setText("asfd");
}
int main(int argc, char *argv[]){
QApplication app(argc, argv);
myWidget window;
window.show();
return app.exec();
}
#include "client.moc"
everything compiles fine, it just doesnt do the processInput() when i press enter in itemnumber lineedit.
EDIT:
it seems that item number is not emitting the returnPressed() signal because i tried replacing it with
connect(itemnumber, SIGNAL(returnPressed()), qApp, SIGNAL(quit()));
and when i pressed enter nothing happened.
The latter should be SLOT:
connect(itemnumber, SIGNAL(returnPressed()), this, SLOT(processInput()));
awnjoor
17th July 2006, 08:05
and i wonder how did i miss that one .. :o
thank you
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.