How to call a method of mainform from another form?



  • on my Qt Widget Project, i have two UIs, mainform.ui and anotherform.ui, like below:

    mainform.h
    anotherform.h

    mainform.cpp
    anotherform.cpp

    mainform.ui
    anotherform.ui

    By the way, it's easy to call anotherform.ui from mainform.cpp / mainform.ui,

    #include "anotherform.h"
    ...
    ...
    AnotherForm *af;
    ...
    ...
    af = new AnotherForm;
    ...
    ...
    af->show();

    But i have difficulties when calling a method of mainform from another form.
    i'm trying including this line of code to anotherform.cpp

    #include "mainform.h"

    but give error, of course trying to create a mainform again will giving us error, any solution?? i think it's not about Qt, its about cpp programming concept LOL :)



  • The preferable method probably is using Signals & Slots: Turn the function to be called, in "main" form, into a Slot. Then add a suitable Signal to the the "other" form. Finally, connect the main form's Slot to the other form's Signal. Now the other form just needs to emit the Signal when needed.

    See here for details:
    http://qt-project.org/doc/qt-4.8/signalsandslots.html

    --

    Alternatively, you could pass a reference (pointer) to the "main" form to the "other" form. Then the other form can use that pointer to call (public) methods of the main form directly. But now the other form needs to know about the main form, which adds dependencies you usually wish to avoid!



  • OK, lets see the scenario below,
    look, i have some files here:

    mainform.h
    mainform.cpp
    mainform.ui

    anotherform.h
    anotherform.cpp
    anotherform.ui

    //code is below
    mainform.h
    @#ifndef MYMAINFORM_H
    #define MYMAINFORM_H

    #include <QMainWindow>
    #include "anotherform.h"

    namespace Ui {
    class MyMainForm;
    }

    class MyMainForm : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MyMainForm(QWidget *parent = 0);
    ~MyMainForm();
    AnotherForm *af;

    private slots:
    void on_pushButton_clicked();

    private:
    Ui::MyMainForm *ui;
    };

    #endif // MYMAINFORM_H@

    mainform.cpp
    @#include "mymainform.h"
    #include "ui_mymainform.h"

    MyMainForm::MyMainForm(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MyMainForm)
    {
    ui->setupUi(this);
    af = new AnotherForm;
    }

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

    void MyMainForm::on_pushButton_clicked()
    {
    af->show();
    }
    @

    anotherform.h
    @#ifndef ANOTHERFORM_H
    #define ANOTHERFORM_H

    #include <QDialog>

    namespace Ui {
    class AnotherForm;
    }

    class AnotherForm : public QDialog
    {
    Q_OBJECT

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

    private slots:
    void on_btnSubmit_clicked();

    private:
    Ui::AnotherForm *ui;
    };

    #endif // ANOTHERFORM_H@

    anotherform.cpp
    @#include "anotherform.h"
    #include "ui_anotherform.h"

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

    }

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

    void AnotherForm::on_btnSubmit_clicked()
    {
    QString name = ui->nameTxt->text();
    this->hide();

    //[--QUESTION START--]
    //i should send name variable to mainform
    //what sould i write here??
    //any suggestion
    //[--QUESTION END--]
    

    }
    @

    I have big mainform with a button on it, if the button clicked, it will show anotherform, it success load anotherform.ui

    on anotherform, i have a textbox and a button, when this button pressed, it should catch the textbox content - then close anotherform.ui - then send the textbox's content to mainform's label (i dont know how to send it to mainform.ui).

    My Question is on //[--QUESTION START--] and //[--QUESTION END--] above, thanks

    :)



  • So you just want to return a result from AnotherForm. Signals & Slots is not needed then. Instead you could simply extend AnotherForm like:

    @class AnotherForm
    {
    [...]

    public:
    QString getResult(void)

    [...]
    

    };@ @AnotherForm::getResult(void)
    {
    return ui->nameTxt->text();
    }@

    And in your "main" form you do:
    @void MyMainForm::on_pushButton_clicked()
    {
    af->exec();
    QString result = af->getResult();
    }@



  • Or, alternatively, with Signals and Slots:
    @class AnotherForm
    {
    [...]

    signals:
    void nameChanged(QString newName);

    [...]
    

    };@ @void AnotherForm::on_btnSubmit_clicked()
    {
    QString name = ui->nameTxt->text();
    emit nameChanged(name);
    }@

    And then in your “main” form you'd do:
    @class AnotherForm
    {
    [...]

    private slots:
        void setName(const QString &newName);
     
        [...]
    

    };@
    @void MyMainForm::on_pushButton_clicked()
    {
    connect(af, SIGNAL(nameChanged(QString)), this, SLOT(setName(QString)));
    af->show();
    }

    void MyMainForm::setName(const QString &newName)
    {
    /* do something with new name! */
    }@



  • WOW, thanks so much, solved :)



  • mulder, you have many opensource software at muldersoft.com, do you create it with Qt??



  • [quote author="okiewardoyo" date="1398993030"]mulder, you have many opensource software at muldersoft.com, do you create it with Qt??[/quote]

    Most of the newer projects are developed with C++ and Qt, some are pure C++. And some of the older stuff was made with Pascal/Delphi.

    (After first Qt experiments, I quickly decided porting all GUI stuff to Qt ^^)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.