PDA

View Full Version : Help with UI Widgets



ReDKiiL
27th March 2015, 20:58
Sup guys.

I'm trying to set a value for my button of another file in this print is in the main but my intention is to put in the socket.cpp.

The error that is happening is that my program crashes. Thanks:)

http://i.cubeupload.com/4OmfAJ.png <- pic from crashes.

Code:


#include "socket.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Socket s;
MainWindow w;
w.show();
w.setWindowTitle("olea");
Ui::MainWindow *abcde;
abcde->btnEnviar->setText("olea");
return a.exec();
}

jefftee
27th March 2015, 21:16
Sup guys.

I'm trying to set a value for my button of another file in this print is in the main but my intention is to put in the socket.cpp.

The error that is happening is that my program crashes. Thanks:)

http://i.cubeupload.com/4OmfAJ.png <- pic from crashes.
The compiler warning points directly at your problem. abcde is an uninitialized pointer variable in line 13 and when you execute line 14, the contents of abcde are unknown.

ChrisW67
27th March 2015, 21:18
You never initialise the abcde pointer, which is why the program crashes. The compiler has even warned you of this.

What you are trying to do will not work in the way you expect even of you fix the pointer though

ReDKiiL
27th March 2015, 21:22
You never initialise the abcde pointer, which is why the program crashes. The compiler has even warned you of this.

What you are trying to do will not work in the way you expect even of you fix the pointer though

Could you give me help on how to do it the right way?
If it's not too much to ask:D

ChrisW67
27th March 2015, 21:30
What you are doing creates a second instance of the generated Ui class that is not related to the one inside the main object. You can change these widgets without affecting the widgets that are visible in the main window.

The main window class has a private member variable, ui, pointing at the objects representing the widgets on screen. For code external to the main window class to access the UI you need to provide a public method in the MainWindow class to allow them to do that.

ReDKiiL
27th March 2015, 21:43
What you are doing creates a second instance of the generated Ui class that is not related to the one inside the main object. You can change these widgets without affecting the widgets that are visible in the main window.

The main window class has a private member variable, ui, pointing at the objects representing the widgets on screen. For code external to the main window class to access the UI you need to provide a public method in the MainWindow class to allow them to do that.

As I write this method? could you give me an example?

#edit
I created a function in the mainwindow class to set the value of the button, and I called him on the socket.
But it does not work, I think it's because the constructor of mainwindow is called 2 times.
How can I call the mainwindow functions without calling the constructor?

jefftee
27th March 2015, 22:01
Look at your MainWindow.cpp and MainWindow.h files. Assuming you created your User Interface (UI) using Qt Designer, then you will have a private variable named ui inside your MainWindow class. You would then use syntax similar to the following to use your various components for your UI:



ui->setupUi(this); // after this statement you can address your various ui components like shown below
ui->btnEnviar->setText("olea");


Remove the abcde stuff from your main() routine and place in the constructor for your MainWindow.

Edit: Also, whatever you were planning on doing with your Socket class in the main() routine should also be moved into your MainWindow class or a different class, but certainly moved out of main().

ReDKiiL
27th March 2015, 22:03
Look at your MainWindow.cpp and MainWindow.h files. Assuming you created your User Interface (UI) using Qt Designer, then you will have a private variable named ui inside your MainWindow class. You would then use syntax similar to the following to use your various components for your UI:



ui->setupUi(this); // after this statement you can address your various ui components like shown below
ui->btnEnviar->setText("olea");


Remove the abcde stuff from your main() routine and place in the constructor for your MainWindow.

Oh that's I need to change the value of the button from another class. Because this class will receive data from there depending on what is received that this button will change.

wysota
27th March 2015, 22:09
Please do not confuse the terms "class" and "object".

jefftee
27th March 2015, 22:09
If you want to change the value of the button from another class, then use signals/slots and emit a signal from your other class, something like this in your other class header file:



signals:
void updateButton(const QString &text);


And then a slot in your MainWindow.h:



public slots:
void onUpdateButton(const QString &text);


And finally the slot itself:



void MainWindow::onUpdateButton(const QString &text)
{
ui->btnEnviar->setText(text);
return;
}


Once you have added the signal and slot, connect them together so that when your other class wants to update the button text, it emits signal updateButton and your onUpdateButton slot will be invoked to update the button, etc.

ReDKiiL
27th March 2015, 22:56
If you want to change the value of the button from another class, then use signals/slots and emit a signal from your other class, something like this in your other class header file:



signals:
void updateButton(const QString &text);


And then a slot in your MainWindow.h:



public slots:
void onUpdateButton(const QString &text);


And finally the slot itself:



void MainWindow::onUpdateButton(const QString &text)
{
ui->btnEnviar->setText(text);
return;
}


Once you have added the signal and slot, connect them together so that when your other class wants to update the button text, it emits signal updateButton and your onUpdateButton slot will be invoked to update the button, etc.

Another help, connect has be placed always on the class of the signal?

wysota
27th March 2015, 23:03
(...) when your other class wants to update the button text, it emits signal (...)

Class emits a signal? :)

jefftee
27th March 2015, 23:08
Another help, connect has be placed always on the class of the signal?
You really need to do some reading before you have a chance at succeeding to write any code. Create a member variable in MainWindow for your Socket. I would add one of the following in the constructor of your MainWindow:

If you have added your member variable as a pointer to a Socket instance named pSocket for example, then use:



connect(pSocket, &Socket:updateButton, this, &MainWindow::onUpdateButton);


If not a pointer but an actual instance named socket, then use:



connect(&socket, &Socket:updateButton, this, &MainWindow::onUpdateButton);



Class emits a signal? :)
When an instance of your other class wants to update the button text, emit a signal...

Touche :)

Edit: Not sure what I did to combine my reply to wysota with my other reply, but it's done and I'm not going to fix it up! :)

ReDKiiL
28th March 2015, 00:11
I tried like this so nothing happens.



//socket.h
#ifndef SOCKET_H
#define SOCKET_H

#include <QObject>
#include <QDebug>

class Socket : public QObject
{
Q_OBJECT
public:
explicit Socket(QObject *parent = 0);
~Socket();

signals:
void enviarSinal(QString z);
public slots:
};

#endif // SOCKET_H
//socket.cpp
#include "socket.h"

Socket::Socket(QObject *parent) : QObject(parent)
{
qDebug() << "Socket iniciado!!!";
emit enviarSinal("Get down");
}

Socket::~Socket()
{

}
//principal.h (MainWindow)
#ifndef PRINCIPAL_H
#define PRINCIPAL_H

#include <QMainWindow>
#include <QDebug>

namespace Ui {
class Principal;
}

class Principal : public QMainWindow
{
Q_OBJECT

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

private:
Ui::Principal *ui;
public slots:
void receberSinal(QString b);
};

#endif // PRINCIPAL_H

//principal.cpp (MainWindow)
#include "principal.h"
#include "ui_principal.h"
#include "socket.h"

Principal::Principal(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Principal)
{
Socket *s = new Socket();
connect(s,SIGNAL(enviarSinal(QString)), this,SLOT(receberSinal(QString)));
qDebug() << s;
ui->setupUi(this);
}

Principal::~Principal()
{
delete ui;
}
void Principal::receberSinal(QString b){
qDebug() << "Recebendo Sinal:";
qDebug() << b;
qDebug() << "====SINAL RECEBIDO====";
}




App output:
http://prntscr.com/6m7wyy

jefftee
28th March 2015, 00:48
Your Socket constructor runs and emits the signal before you have made the connection. I know you're just trying to test the signal/slot, but I presume in your actual implementation, you would emit the signal after you have received some data on the Socket, etc.

If you want to just try a test, remove the emit from line 27 and add the following after line 73:



emit s->enviarSinal("Get down");

ReDKiiL
28th March 2015, 01:22
Thank you,Yes I am wanting to do some tests, in the future my code will be but complete.

jefftee
28th March 2015, 01:22
So did that work?

ReDKiiL
28th March 2015, 01:32
So did that work?

Yep ;)

http://prntscr.com/6m8qsk