PDA

View Full Version : Beginner problem with connect



lucastonon
13th July 2011, 02:13
So there's the source files that qt created for me (main.cpp and program.cpp). I made with Qt Designer the basics of a dialog, and now I'd like to do something like:
Creating window1.cpp and window1.h;
Creating a class like class wnd1 and put some functions and slots to use the connect function to handle buttons' signals.

So far what I could do was handling this signals inside program.cpp, but everything I tried to do that at window1.cpp failed (like not having connect accept my class, slots not being allowed to be declared, etc). How could be an intelligent way to do that? I don't want to do that all inside program.cpp, it would be a mess because the program will have lots of tabs and controls. I hope my question is clear. If possible, I'd like some examples.

Thanks.

Santosh Reddy
13th July 2011, 02:40
If window1 class has signals / slots then you should be using Q_OBJECT macro at the beginning of the class definition, check if you are missing this.

lucastonon
13th July 2011, 19:52
program.cpp


#include "global.h"
#include "program.h"
#include "window1.h"
#include "ui_program.h"

program::program(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::program)
{
ui->setupUi(this);
wnd1 w1;
w1.Initialize();

}

program::~program()
{
delete ui;
}


window1.h


#ifndef WINDOW1_H
#define WINDOW1_H
#include <QObject>

class wnd1 : public QObject {
Q_OBJECT
public:
void Initialize();

private slots:
void test();


};
#endif // WINDOW1_H


window1.cpp


#include "global.h"
#include "window1.h"
#include "program.h"

program oProg;



void wnd1::Initialize() {
QPushButton *b = oProg.centralWidget()->findChild<QPushButton *>("button1"); // seems i cant use oProg. some reason
wnd1 w1;
w1.connect(b, SIGNAL(clicked()), SLOT(test()));

}


void wnd1::test() {
//do something
}


in global.h


#include <QtGui/QApplication>
#include <QtGui/QMessageBox>


15: error: no matching function for call to ‘wnd1::connect(QPushButton*&, const char [11], const char [8])’

Thanks.

Santosh Reddy
13th July 2011, 20:31
Use it this way


//program.cpp
program::program(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::program)
{
ui->setupUi(this);
wnd1 * w1 = new wnd1(this);
QPushButton *b = ui->pushButton;

connect(b, SIGNAL(clicked()), w1, SLOT(test()));
}

lucastonon
13th July 2011, 20:37
That line you asked me is the way I found at the internet to get a 'handle' to an object created by Qt Designer, instead of manually creating it with commands. It works fine in program.cpp but not in window1.cpp.
Thanks.

Santosh Reddy
14th July 2011, 03:06
Looks like you still have to figure out the basic object creation and scope work (it's C++ stuff)


//program.cpp
wnd1 w1; //this will create object on stack and will be destroyed as soon as function returns
w1.Initialize(); //this is ok



//window1.cpp
program oProg; //this not good, you are creating a global QMainWindow, that means you are trying to create a widget even before QApplication is created

void wnd1::Initialize() {
QPushButton *b = oProg.centralWidget()->findChild<QPushButton *>("button1"); // you are not supposed to get the member widgets of other class this way, it will work but will end up in problems later
wnd1 w1; //this will create object on stack and will be destroyed as soon as function returns
w1.connect(b, SIGNAL(clicked()), SLOT(test())); //there is no such version of connect function, hence the error, and moreover it does not make sense to connect a object which will be deleted before this function returns. So even if you were able to get the correct version of the function, your slot will never get called, as the object itself is destroyed before this function returns
}


Please try, as I suggested in my earlier post

lucastonon
14th July 2011, 03:56
Mmm I got it, but I wanted to do that (connecting) in another .cpp file, just because of organization, can't it be done?

Another question using your example:



//program.cpp
program::program(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::program)
{
ui->setupUi(this);

wnd1 *w1 = new wnd1;
connect(ui->button1, SIGNAL(clicked()), w1, SLOT(test()));

}

//window1.cpp
void wnd1::test() { //is it ok doing that in this function?[/COLOR]
program *ep = new program;
QMessageBox::information(ep, "a", "b");
delete ep;
}


Thanks

Santosh Reddy
14th July 2011, 04:02
it can be done, (and is done most of times this way), you can create a signal of program class (instead of button signal) and connect to win1 class objects

lucastonon
14th July 2011, 04:21
You mean creating a signal for something like a tab? How to do that? :s
Thanks

Santosh Reddy
14th July 2011, 04:31
here is an example

//program.h
#include <QtGui>
#include "ui_program.h"
class wnd1;
class program : public QMainWindow, public
{
Q_OBJECT;
public:
explicit program(QWidget * parent = 0);
signals:
void openButtonClicked(void);
private:
Ui::program * ui;
wnd1 * w1;
};

//program.cpp
#include "program.h"
#include "window1.h"

program::program(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::program()),
w1(new wnd1(this))
{
ui->setupUi(this);
connect(this, SIGNAL(openButtonClicked()), w1, SLOT(test()));
}

program::~program()
{
delete ui;
}

//window1.h
#include <QtGui>
class wnd1 : public QObject
{
Q_OBJECT;
public:
explicit wnd1(QObject * parent = 0);
public slots:
void test(void);
};

//window1.cpp
#include "window1.h"
wnd1::wnd1(QObject * parent) : QObject(parent)
{
;
}

void wnd1::test(void)
{
;//do something
}

lucastonon
14th July 2011, 04:59
it can be done, (and is done most of times this way), you can create a signal of program class (instead of button signal) and connect to win1 class objects

I don't think you got. What I understood from this quoted post was that if I had a tab widget, I could connect example: tab1 to wnd1(window1.cpp), tab2 to wnd2(window2.cpp); and then every control from the connected tab would signal the connected object, but forget that. I just wanted to do something like:


//program.cpp
program::program(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::program)
{
ui->setupUi(this);

wnd1 w1;
w1.Initialize();

}

//window1.cpp
void wnd1::Initialize() {
connect(ui->button1, SIGNAL(clicked()), this, SLOT(test1()));
connect(ui->button2, SIGNAL(clicked()), this, SLOT(tes2t()));
connect(ui->button3, SIGNAL(clicked()), this, SLOT(test3()));
connect(ui->button4, SIGNAL(clicked()), this, SLOT(test4()));
connect(ui->button5, SIGNAL(clicked()), this, SLOT(test5()));
// but i don't know how to get a handle the buttons in window1.cpp since 'ui' is from program.cpp
}


Sorry for the misunderstanding.

Santosh Reddy
14th July 2011, 05:55
// but i don't know how to get a handle the buttons in window1.cpp since 'ui' is from program.cpp
I was trying to tell you that, make the connections in program.cpp not is window1.cpp, move the connect statements to program class ctor (this is a standard way doing).
In program.cpp you will have handles to buttons, and you also know that wnd1 class has an public slot testx()

lucastonon
14th July 2011, 15:49
Ok I'll make the connections at program.cpp. But in case in window1.cpp I need to get the text of a text edit I would need to have ui->textEdit1 in window1.cpp, but I can only use that in program.cpp

Santosh Reddy
14th July 2011, 16:32
You are still getting it worng, do not create wnd1 variable in program.cpp constructor. (it will not work) also, refer to my post (Post #4) for example to create objects

I can see you are complicating your situation, Please review your code again.

Problem: You are tyring to create a object of program class with in a slot connected to a signal emitted by program class it self, why do you need to do it this wa? I am not sure of your requrements, but you don't want this.

Either create program class object in wnd1 class or create wnd1 class object in program class, but don't do both:eek: