PDA

View Full Version : Connecting two objects form another object



Doko
30th March 2015, 21:14
Hy

I would like to ask someone for help. I wanted to make a gui server:) so I created a gui application and in main class I created my server (because if I created it in MainWindow class I had problems with incomingConnection). It was not a problem to connect server class with mainwindow class, but problem arises when I try to connect another object declared in server class with mainwindow, I do not know how to pass object address, so I ask for help. To further illustrate my problem I attached piece of code:



#include "mainwindow.h"
#include <QApplication>
#include "server.h"

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

Server ServerTcp;
QObject::connect(&ServerTcp,SIGNAL(SetInfo(QString)),&w,SLOT(GetInfo(QString)));
ServerTcp.StartServer(&w);

return a.exec();
}



#include "server.h"
#include "client.h"

Server::Server(QObject *parent) :
QTcpServer(parent)
{
}

void Server::StartServer(QMainWindow *object)
{
if(listen(QHostAddress::Any,1234)){
obj = object;
emit SetInfo("Started");
}
else{
emit SetInfo("Not started!");
}
}

void Server::incomingConnection(int handle)
{
Client *clientT = new Client(this);
connect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
clientT->SetSocket(handle);
}


Thank you for reply

jefftee
30th March 2015, 21:52
If I understand what you're trying to do, shouldn't GetInfo be the signal (i.e. request to get info) and the slot be the SetInfo (i.e. set the info provided by the GetInfo signal)?

Your cleintT variable is a local pointer, which will go out of scope as soon as your Server::incomingConnection method finishes. If you wish to later signal this object, you should save your clientT pointer as a member variable, then you can use to signal in your Server::StartServer method as follows (assuming member pointer is called m_clientT):



void Server::StartServer(QMainWindow *object)
{
if(listen(QHostAddress::Any,1234)){
obj = object;
emit m_clientT->SetInfo("Started");
}
else{
emit m_clientT->SetInfo("Not started!");
}
}

Is that what you are looking for?

P.S. is obj a member variable or what's the purpose for obj = object?

Doko
30th March 2015, 22:37
I already connected server class with mainwindow, I want to connect clientT class with mainwindow, so that get information out of clientT class, so as you see from code when I create server I call function startServer where I want to pass address of mainwindow, which I store as "QMainWindow *obj" as global variable in that class and than use this address in another function "incomingConnection" to connect newly formed class with mainwindow. SetInfo(QString) are signal that are named the same in server and client class.
For example when someone connects to server I want that client class passed "Client connected" to mainwindow where text is displayed in QTextEdit widget. If it would be console app I would do qDebug << "Client connected", but because it is gui app there is this problem to pass data between objects, so basicaly I have three objects, two of them are defined in main.cpp and client object is locally defined in one those static objects. I know that when function finishes clientT will go out of scope, but just that brief I want this connection to work, and again when another incomingConnection comes, and so on till I close the program.

Added after 11 minutes:

Actually there is also missing disconnect.
If I could only somehow pass address of mainwindow in this obj. Or is there some other way to resolve this problem of connecting two objects?



void Server::incomingConnection(int handle)
{
Client *clientT = new Client(this);
connect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
clientT->SetSocket(handle);
disconnect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
}

jefftee
30th March 2015, 22:53
So you pass the MainWindow address in StartServer method and save in the obj member variable, correct?

Either pass the obj variable to the constructor of the Client or add a setter method to the client that can save the MainWindow address.

Is that what you're looking for?

anda_skoa
31st March 2015, 07:05
void Server::incomingConnection(int handle)
{
Client *clientT = new Client(this);
connect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
clientT->SetSocket(handle);
}


No & at client, this is already a pointer, same for obj.


Actually there is also missing disconnect.


void Server::incomingConnection(int handle)
{
Client *clientT = new Client(this);
connect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
clientT->SetSocket(handle);
disconnect(&clientT,SIGNAL(SetInfo(QString)),&obj,SLOT(GetInfo(QString)));
}
If you disconnect right after connecting, why connect in the first place?

Cheers,
_

Doko
31st March 2015, 12:07
Ok, I see it was really not good to disconnect right away.


So you pass the MainWindow address in StartServer method and save in the obj member variable, correct?

Either pass the obj variable to the constructor of the Client or add a setter method to the client that can save the MainWindow address.

I understand, but I dont know how to do that. If I pass and than save MainWindow address in some object, I can not access MainWindow by that address.

Simplified example:


int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

Server ServerTcp;
ServerTcp.StartServer(&w); //is that the right way to send address??

return a.exec();
}

#include "server.h"
#include "mainwindow.h"

Server::Server(QObject *parent) :
QTcpServer(parent)
{
}

void Server::StartServer(QMainWindow *object)
{
if(listen(QHostAddress::Any,1234)){
obj = object;
obj->GetInfo("Started"); //<--- ? Does not work (does not recognize GetInfo function)
}
else{
obj->GetInfo("Not started!");
}
}

obj is declared in Server class under private: as QMainWindow *obj;
why I can not access this function (void GetInfo(QString str) form server object, declared as public slot in MainWindow class)
What am I doing wrong?

anda_skoa
31st March 2015, 15:05
obj is declared in Server class under private: as QMainWindow *obj;




function (void GetInfo(QString str) form server object, declared as public slot in MainWindow class)
What am I doing wrong?
You have your answer right there.

jefftee
31st March 2015, 15:13
obj is declared in Server class under private: as QMainWindow *obj;
why I can not access this function (void GetInfo(QString str) form server object, declared as public slot in MainWindow class)
What am I doing wrong?
I see you are passing a QMainWindow* to Server::StartServer. Have you tried passing your MainWindow pointer instead?

Please show the actual error. Compile error, run-time error, etc?

Also post your MainWindow.h using
tags please.

Doko
31st March 2015, 16:15
I attached MainWindow.h, mainwindow.cpp and server.h

I tried to do another simple program, I created mainwindow and in this object I created two dialogs that were declared with pointers (note that mainwindow is not declared with poiter, but as I understand is a object), so I passed address of the first dialog in the constructor of second dialog, everything else was the same as illustrated by code above and it worked perfectly, I was able to call a function of first dialog from the second dialog (example: dialog1->doSomething(), dialog1 was declader in second dialog), but I think that the issue is because mainwindow is not declared with pointer... I dont know how to do it differently.

Issues:
C:\Qt test\Control\server.cpp:13: error: 'class QMainWindow' has no member named 'GetInfo'
obj->GetInfo("Started");
^
C:\Qt test\Control\server.cpp:16: error: 'class QMainWindow' has no member named 'SetInfo'
obj->SetInfo("Not started!");
^


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:
void GetInfo(QString str);

private:
Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

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

void MainWindow::GetInfo(QString str)
{
ui->textEdit->append(str);
}


#ifndef SERVER_H
#define SERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QMainWindow>

class Server : public QTcpServer
{
Q_OBJECT
public:
explicit Server(QObject *parent = 0);
void StartServer(QMainWindow *object);

protected:
void incomingConnection(int handle);

public slots:

private:
QMainWindow *obj;

};

#endif // SERVER_H

jefftee
31st March 2015, 16:41
The error tells you exactly what the problem is. Your MainWindow inherits from QMainWindow, correct? So a MainWindow is a QMainWindow but a QMainWindow is *not* a MainWindow.

The obj pointer you save needs to be a pointer to a MainWindow, not a QMainWindow.

P.S. Look at the documentation for QMainWindow. Do you see a GetInfo method that returns void and has a QString as an argument? Nope, but your MainWindow class does.

Doko
31st March 2015, 17:29
Thank you very much. It was so obvious but I could not figure it out.