0

I need to edit a QLabel from MainWindow's UI in another source file. I've tried messing around with singals and slots, but honestly I'm completely lost and the Qt documentation doesn't help me in this exact situation. I understand that this has been asked in the past, but I have not found a solution that works for me. I'm new to Qt, and C++ in general.

I have the following code (greatly simplified):

"mainwindow.h":

#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();
    void setFoo(char* text);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

"mainwindow.cpp"

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

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

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

void MainWindow::setFoo(char* text) {
    ui->fooLabel->setText(text);
}

"secondwindow.h"

#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H

#include <QWidget>

namespace Ui {
class SecondWindow;
}

class SecondWindow: public QWidget {
    Q_OBJECT

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

private:
    Ui::SecondWindow*ui;
}

#endif // SecondWindow_H

"secondwindow.cpp"

#include "secondwinodw.h"
#include "ui_secondwinodw.h"
#include "mainwindow.h"

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

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

void SecondWindow::on_fooButton_clicked() {
    MainWindow::setFoo("example");//The method is private so this is not possible, but this is my goal
}

When a user clicks on fooButton, I need to access and edit the MainWindow's UI QLabel(or a public method that does this). The secondwindow is not being created in the main() function

void MainWindow::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_A:
        if (event->modifiers()==Qt::ShiftModifier) {
            SecondWindow*secwind= new SecondWindow();
            secwind->show();
        }
        break;
    }
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Mr. Knot
  • 23
  • 2
  • where do you create the objects of those classes? – eyllanesc Jun 26 '18 at 18:39
  • 1
    actually `MainWindow::setFoo` is public. maybe pass a pointer to `MainWindow` into `SecondWindow` and use that pointer to call `setFoo` – Thomas Jun 26 '18 at 18:49
  • Possible duplicate of [Access Qt ui from another class](https://stackoverflow.com/questions/23669045/access-qt-ui-from-another-class) – Mohammad Kanan Jun 26 '18 at 20:28

1 Answers1

2

In OOP the ones that interact are the objects, not the classes or the files, that is, the following expression:I need to edit QLabel from MainWindow's UI in another source file It does not make sense, what you should say is that an object of the MainWindow class is modified by another object of the SecondWindow class. The files do not make the program, the interaction between objects do it.

I'm assuming that both objects are created in the main.cpp:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w1;
    SecondWindow w2;

    w1.show();
    w2.show();

    return a.exec();
}

Now if I go to attack the main problem, Qt handles the concept of signals and slots, so we will use it, as the action to a SecondWindow object will cause the information to be sent, I will create a signal that carries that information:

secondwindow.h

#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H

#include <QWidget>

namespace Ui {
class SecondWindow;
}

class SecondWindow: public QWidget {
    Q_OBJECT

public:
    explicit SecondWindow(QWidget *parent = 0);
    ~SecondWindow();
signals:
    void messageChanged(const QString & message); // <---
private slots:
    void void SecondWindow::on_fooButton_clicked();
private:
    Ui::SecondWindow*ui;
}

#endif // SecondWindow_H

when the button is pressed, the signal with the information must be emitted

secondwindow.cpp

...
void SecondWindow::on_fooButton_clicked() {
    emit messageChanged("example");//The method is private so this is not possible, but this is my goal
}

Now we go to the receiver's side, how will we get a slots, you have done it but do not use char *, that's C, we're using C++ and much better we're using Qt, it's best to use QString:

mainwindow.h

....
void setFoo(const QString & text);

mainwindow.cpp

...
void MainWindow::setFoo(const QString & text) {
    ui->fooLabel->setText(text);
}

And finally we make the connections:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w1;
    SecondWindow w2;

    QObject::connect(&w2, &SecondWindow::messageChanged, &w1, &MainWindow::setFoo); 

    w1.show();
    w2.show();

    return a.exec();
}

update:

void MainWindow::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_A:
        if (event->modifiers()==Qt::ShiftModifier) {
            SecondWindow*secwind= new SecondWindow();
            connect(secwind, &SecondWindow::messageChanged, this, &MainWindow::setFoo);
            secwind->show();
        }
        break;
    }
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Thank you, everything works perfectly. My only problem is secondwindow is not being created in the main() function. It's being called in a keyPressEvent (which I should have specified, sorry). How would I go about accessing the main() function's MainWindow, so I can use "connect" inside the keyPressEvent. – Mr. Knot Jun 26 '18 at 20:47
  • I appreciate the fast response. Edited the code to the bottom of the question. – Mr. Knot Jun 26 '18 at 20:52
  • @Mr.Knot edit your question and place it there please, do not edit my answer – eyllanesc Jun 26 '18 at 20:57
  • I accidentally edited your question, sorry. I updated the question, like you requested. – Mr. Knot Jun 26 '18 at 21:04
  • Truly thankful for your help. Now it's just a matter of fully understanding slots and signals. – Mr. Knot Jun 26 '18 at 21:14
  • The answer is great, and should deserve more upvotes! +1 – Eric Jan 04 '22 at 07:32