Access to UI elements from another class qt-c++



  • Hello,
    I have a problem with accessing ui elements from another class(with instance). I have a second QMainWindow in my application, I can access in mainWindow.cxx, write.cxx and secondWindow.cxx class all ui elements but not in read.cxx class. When I click on "pushButton2" on the "secondWindow", nothing happens, no reaction. My code looks like following. Where is my mistake? Thank you for any help.

    Main Window
    @
    -----------------------------mainWindow.h----------------------------------
    #ifndef __mainWindow_h
    #define __mainWindow_h

    #include "ui_mainWindow.h"
    #include "app.h"

    class mainWindow : public QMainWindow
    {
    friend class app;
    friend class write;
    igstkStandardClassBasicTraitsMacro(mainWindow, QMainWindow);
    Q_OBJECT

    public:
    igstkStateMachineMacro();

    mainWindow();
    virtual ~mainWindow();
    void createSignalAndSlots();

    public slots:
    void openSecondWindow();
    void mainWindowTest();

    private:
    Ui::mainWindow m_mainWindowUI;
    };
    #endif

    -----------------------------mainWindow.cxx----------------------------------
    #include "mainWindow.moc"
    #include "mainWindow.h"
    #include "secondWindow.h"
    #include "read.h"
    #include "write.h"

    mainWindow::mainWindow() : m_StateMachine(this)
    {
    m_mainWindowUI.setupUi(this);
    createSignalAndSlots();
    }

    mainWindow::~mainWindow(){}

    void mainWindow::createSignalAndSlots()
    {
    connect(m_mainWindowUI.menuOpenAction, SIGNAL(triggered()), this, SLOT(openSecondWindow()));
    connect(m_mainWindowUI.pushButton1, SIGNAL(clicked()), this, SLOT((mainWindowTest()));
    connect(m_mainWindowUI.pushButton2, SIGNAL(clicked()), write::instance(), SLOT((writeTest()));
    }

    void mainWindow::openSecondWindow()
    {
    secondWindow *secondWin = new secondWindow();
    secondWin->show();
    }

    void mainWindow::mainWindowTest()
    {
    m_mainWindowUI.pushButton1->setEnabled(true); //OK, it works
    }

    -----------------------------write.h----------------------------------
    #pragma once

    #include "mainWindow.h"

    class write : public QObject
    {
    Q_OBJECT

    public:
    static write *instance();
    write();
    virtual ~write() {}

    public slots:
    void writeTest();

    protected:
    app *m_writeUI;
    static write *m_write;

    private:
    };

    -----------------------------write.cxx----------------------------------
    #include <write.moc>
    #include "mainWindow.h"
    #include "write.h"

    write *write::m_write= NULL;

    write::write()
    {
    m_writeUI = dynamic_cast<app*>(QApplication::instance());
    }

    write *write::instance()
    {
    if(m_write == NULL)
    m_write = new write();

    return m_write;
    

    }

    void write::writeTest()
    {
    m_writeUI->m_mainWindowUI.mainQLabelTest->setText("main label test"); //OK, it works
    }
    @

    Second Window
    @
    -----------------------------secondWindow.h----------------------------------
    #ifndef __secondWindow_h
    #define __secondWindow_h

    #include "ui_secondWindow.h"
    #include "app.h"

    class secondWindow : public QMainWindow
    {
    friend class read;
    friend class app;
    igstkStandardClassBasicTraitsMacro(secondWindow, QMainWindow);
    Q_OBJECT

    public:
    igstkStateMachineMacro();

    secondWindow(QWidget *parent= 0);
    virtual ~secondWindow();
    void createSignalAndSlots();
    

    public slots:
    void secondWindowTest();

    private:
    Ui::secondWindow m_secondWindowUI;
    };
    #endif

    -----------------------------secondWindow.cxx----------------------------------
    #include "secondWindow.moc"
    #include "secondWindow.h"
    #include "read.h"

    secondWindow::secondWindow(QWidget *parent) :m_StateMachine(this)
    {
    m_secondWindowUI.setupUi(this);
    createSignalAndSlots();
    }

    secondWindow::~secondWindow(){}

    void secondWindow::createSignalAndSlots()
    {
    connect(m_secondWindowUI.pushButton1, SIGNAL(clicked()),this, SLOT(secondWindowTest()));
    connect(m_secondWindowUI.pushButton2, SIGNAL(clicked()), read::instance(), SLOT(readTest()));
    }

    void secondWindow::secondWindowTest()
    {
    m_secondWindowUI.pushButton1->setEnabled(true); //OK, it works
    }

    -----------------------------read.h----------------------------------
    #pragma once

    #include "secondWindow.h"

    class read : public QObject
    {
    Q_OBJECT

    public:
    static read *instance();
    read();
    virtual ~read() {}

    public slots:
    void readTest();

    protected:
    app *m_readUI;
    static read *m_read;

    private:
    };

    -----------------------------read.cxx----------------------------------
    #include <read.moc>
    #include "secondWindow.h"
    #include "read.h"

    read *read::m_read= NULL;

    read::read()
    {
    m_readUI = dynamic_cast<app*>(QApplication::instance());
    }

    read *read::instance()
    {
    if(m_read == NULL)
    m_read = new read();

    return m_read;
    

    }

    void read::readTest()
    {
    m_readUI->m_secondWindowUI.secondQLabelTest->setText("second label test"); //ERROR, it works but no reaction
    }
    @

    Main and GUI Initializations

    @
    -----------------------------app.h----------------------------------
    #pragma once

    class mainWindow;
    class secondWindow;

    class app : public QApplication
    {
    Q_OBJECT
    igstkStandardClassBasicTraitsMacro(app, QApplication);

    friend class read;
    friend class write;
    friend class mainWindow;
    friend class secondWindow;

    public:
    app(int& argc, char **argv);
    virtual ~app() {}

    protected:
    mainWindow *m_mainWin;
    secondWindow *m_secondWin;

    void setMainWindow(mainWindow *mainWindow)
    {
    m_mainWin = mainWindow;
    }

    void setSecondWindow(secondWindow *secondWindow)
    {
    m_secondWin = secondWindow;
    }
    private:
    };

    -----------------------------app.cxx----------------------------------
    #include "app.moc"
    #include "app.h"

    app::app(int& argc, char **argv): QApplication(argc, argv), m_StateMachine(this){
    }

    -----------------------------main.cxx----------------------------------
    #include "mainWindow.h"
    #include "secondWindow.h"
    #include "app.h"

    int main(int argc, char** argv)
    {
    app app(argc, argv);

    mainWindow main;
    secondWindow second;

    app.setMainWindow(&main);
    app.setSecondWindow(&second);

    main.showMaximized();

    return app.exec();
    }
    @


  • Lifetime Qt Champion

    Hi,

    Please, take a look at the examples in the Qt documentation. They explain very well how to use signals & slots to update ui elements from one class based on changes in another one.

    Could you explain what you are trying to achieve ? I don't really understand why the complexity of your code to update the text from a QLabel.

    You are mixing several complex concepts here and that doesn't look clean. For example, you rarely need to inherit QApplication, and in your code, I don't see the use case. Also why do you need two singleton classes and all the "friending" ?

    One last thing, does your code compile ?

    Hope my questions will help



  • Also, in general, posting huge walls of text is not a very good way to get attention. Especially for such a trivial problem that can be summed up in a few lines of example code. It is hardly necessary to read through all your code for such a trivial answer.

    Accessing a UI element of another class is just like accessing any other accessible member of any other class. There is no rocket science to it.



  • [quote author="SGaist" date="1366734672"]Hi,

    Please, take a look at the examples in the Qt documentation. They explain very well how to use signals & slots to update ui elements from one class based on changes in another one.

    Could you explain what you are trying to achieve ? I don't really understand why the complexity of your code to update the text from a QLabel.

    You are mixing several complex concepts here and that doesn't look clean. For example, you rarely need to inherit QApplication, and in your code, I don't see the use case. Also why do you need two singleton classes and all the "friending" ?

    One last thing, does your code compile ?

    Hope my questions will help

    [/quote]

    Hi,

    Examples unfortunately does not help: ( and it is actually the shortest code from whole application. Main goal was accessing ui elements of second QMainWindow in class read.cxx. I can access ui-elements from mainWindow (in this case mainQLabelTest) in class "write.cxx" but I can't access ui-elements (in case secondQLabelTest) from secondWindow in class read.cxx. If I press the button "pushButton2" on secondwindow, it happens nothings and and I can't find out why? and yes it is compilable and executable.

    Thank you.



  • [quote author="utcenter" date="1366735411"]Also, in general, posting huge walls of text is not a very good way to get attention. Especially for such a trivial problem that can be summed up in a few lines of example code. It is hardly necessary to read through all your code for such a trivial answer.

    Accessing a UI element of another class is just like accessing any other accessible member of any other class. There is no rocket science to it.[/quote]

    Hi,

    Yes I know that it is tedious, but had no other choice in order to express precisely the problem.

    Thank you.


  • Lifetime Qt Champion

    Well, your code, in this state does not compile (i.e. not any declaration of m_StateMachine nowhere).

    If your complete software is as convoluted as what you posted, then I would advise to refactor it from the ground up.

    Is your goal only to change the label from secondWindow based on a click of button on mainwindow ?



  • No that was not my goal qlabel is here just an example. Actually I just want to distribute my whole code. When I click on pushButton2 on the secondWindow, the processing of SLOT "readtest()" and accessing the ui's from secondWindow should take place in read.cxx, not in secondWindow.cxx. The secondWindow has many ui-elements that I want to use in read.cxx and may be in other classes too. Sorry you can remove all the m_StateMachine(), igstkStandardClassBasicTraitsMacro(bla, bla) and igstkStateMachineMacro() then it changes nothing.


  • Lifetime Qt Champion

    Then, if I may, you're "doing it wrong".

    Your read class should not know anything about your GUI classes. It adds a tight coupling that will blow up in your hand once you start making modifications to one class or the other.

    Define an interface for your read class, and externally connect it to your GUI.

    i.e. :
    @
    class MyReadClass : public QObject
    {
    Q_OBJECT
    public:
    void MyReadClass(QObject *parent = 0):
    QObject(parent)
    {}

    signals:
    void messageChanged(const QString& message);

    public slots:
    void startSomeWork()
    {
    doSomeWorkImpl();
    }

    private:
    void doSomeWorkImpl()
    {
    // do your stuff
    emit messageChanged(tr("Done something"));
    }
    };

    class MyCoolWindow : public QWidget
    {
    Q_OBJECT
    public:
    MyCoolWindow(QWidget *parent = 0) :
    QWidget(parent),
    _myLabel(new QLabel(tr("empty"))
    {
    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->addWidget(_myLabel);
    }

    public slots:
    void updateLabel(const QString& text)
    {
    _myLabel->setText(text);
    }

    private:
    QLabel *_myLabel;
    };

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    MyReadClass myReadClass;
    MyCoolWindow myCoolWindow;
    QObject::connect(&myReadClass, SIGNAL(messageChanged(QString)), &myCoolWindow, SLOT(updateLabel(QString)));
    QTimer::singleShot(1000, &myReadClass, SLOT(startSomeWork()));
    return app.exec();
    }
    @

    Again, please, read the examples and demos from Qt's sources, they cover a very large ground. If you are splitting your code: draw some class diagrams before, do some architecture tests. Without that you will end up with some weird beast.

    Hope it helps


Log in to reply
 

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