Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Access to other class variables



  • Hi
    In my mainwindow I have a qtabwidget. Each tab has its own .ccp/.h/.ui - file and should show the result of a different network-request with different parameters and a different request method. The data (parameters, request-method) is in a QString in the .cpp file of the tabwidget.
    So when a tabwidget emits the signal "currentChanged", it calls a network-request-function and the class:

    my mainwindow.h contains:

    #include "tab_balance.h"
    #include "tab_charges.h"
    [...]
    public slots:
            void network_request(QWidget *tab_target);
    private:
        Ui::MainWindow *ui;
        
        tab_balance _gotobalances;
        tab_charges _gotocharges;
    

    my mainwindow.cpp contains:

    connect(ui->tabWidget, &QTabWidget::currentChanged, [&]() {
            if (ui->tabWidget->currentWidget()->objectName() == _gotobalances.objectName()) {
                network_request(&_gotobalances);
            }
            else if (ui->tabWidget->currentWidget()->objectName() == _gotocharges.objectName()){
                  network_request(&_gotocharges);
            }
    });
    [...]
    void MainWindow::network_request(QWidget *tab_target)  
    {
    [...]
    connect(manager, SIGNAL(finished(QNetworkReply*)), tab_target, SLOT(make_request_answer(QNetworkReply*)));
    }
    

    my tab_charges.h and tab_balance.h contain:

    public:
            explicit tab_charges(QWidget *parent = nullptr);
            ~tab_charges();
        
            QString tab_URL;
            QMap<QString, QString> parameters;
            QString endpoint;
       
        private slots:
            void make_request_answer(QNetworkReply *reply);
    

    My tab_charges.cpp and tab_balance.cpp contain:

    void tab_balance::make_request()
    {
        //endpoint
        endpoint = "get";  // or endpoint="post"
    
        //request-URL
        tab_URL = "https://api.example.com/[...]";
    
        //parameters
        parameters.insert("limit","4");  //or other/additional parameters
    }
    

    The values of the three QStrings in "void tab_balance::make_request()" are different in the .cpp-files (other method, other parameters).

    void tab_balance::make_request_answer(QNetworkReply *reply)
    {
        if(reply->error())
            {
                ui->textBrowser->setText(reply->errorString());
            }
            else
            {
                ui->textBrowser->setText(reply->readAll());
        }
    }
    

    The connect works as it should - it connects to tab_charges.cpp/tab_balance.cpp to the private slot "make_request_answer..." depending on the tabwidget that changed.

    However, I can not access the values of the three QStrings (in tab_charges/tab_balace) from "void MainWindow::network_request(QWidget *tab_target)".
    I need to access these values, because e.g. the request-method is different and I have to define the method before the network-request starts.

    This is a debug-result when qtabwidget "tab_charges" is active:

    qDebug() << "classnames" << tab_target->metaObject()->className() << "---" << _gotocharges.metaObject()->className();
    
    //result: "classnames tab_charges --- tab_charges"
    

    How can I access the three QStrings of the respective .cpp-file without if-clauses like (if (tab_target->metaObject()->className() == _gotocharges.metaObject()->className()) [...]). There should be a better way, because the "connect" works without all that.

    Thanks for your help



  • @Mark58 said in Access to other class variables:

    How can I access the three QStrings of the respective .cpp-file without if-clauses

    There are many ways to skin a cat :) I believe what you are saying is: "I have multiple tab widgets. Each one has its own relevant data. The slot handling the signal needs to be back in the main window, but needs to know what that data is, given it knows which tab has been clicked."

    So what about subclassing the widgets placed on the tabs so that they share a common base class which offers a method that returns the necessary data? Like:

    MyDataWidget *w = qobject_cast<MyDataWidget *>ui->tabWidget->currentWidget();
    if (w != nullptr)
        relevantData = w->tabRelevantDataCommonMethod();
    


  • @JonB Thanks for your answer. However, I'm not sure if this is the best solution for me.

    In other words: I have the class name as a string

    QString classname = tab_target->metaObject()->className();
    

    And in the next step I want to get access to the value of a string of this class. So I need "something" that gives my string access to the class.


  • Lifetime Qt Champion

    @Mark58 Basic c++ - one class needs the pointer of another class if it wants access it's functions. So give the one class the pointer to the other and you're done.



  • @Mark58 said in Access to other class variables:

    In other words: I have the class name as a string
    And in the next step I want to get access to the value of a string of this class. So I need "something" that gives my string access to the class.

    You are coding in C++, not Python. That cannot be done in the C language, by design! And also you sound like you're confusing classes with instances. You can go down @Christian-Ehrlicher's approach, or mine, but string --> class/instance is a no-no :)



  • @Christian-Ehrlicher
    Thanks for your hint.
    However, I have no idea how to give the pointer to the other class.
    From mainwindow.cpp I do have access to the variables in tab_charges.cpp/tab_balance.cpp when I use

    _gotobalances->endpoint or _gotochages->endpoint
    

    Now I made the following changes:

    tab_balance *_gotobalances = new tab_balance;
    tab_charges *_gotocharges = new tab_charges;
    

    When I am in

    void MainWindow::network_request(QWidget *tab_target) 
    

    I only know the class name (either "tab_charges" or "tab_balance") which comes from "tab_target->objectName()". tab_target->endpoint does not exist.

    How do I have to set the pointer to access the appropriate "endpoint"? I appreciate your help.


  • Lifetime Qt Champion

    I really really would suggest you a god good C++ book, sorry. This is basic c++ which is needed for Qt.



  • @Mark58

    Pass the instance with constructor.

    A *a = new A();
    B *b = new B(a);
    

    Something like that :)
    Of course you have to alter the header files accordingly.

    To access private vars from your class, you need public getters and setters. Even if you have the pointer to that class, it doesn't mean, that you can access everything.

    Add public functions to your tab_targets that allow you to access your private data.

    // Tab_balance / charges header
    {
    QString endpoint(){ return m_endpoint; }
    // where "m_endpoint" = actual name of your private endpoint  string variable
    }
    

    Then you can do this:
    tab_balance->endpoint(); and you will receive the string that is stored in tab_balance.

    Btw:
    @JonB s first reply already provides the "cleanest" solution. All you have to do, is to create a base class for your tabTargets with has data access functions. Then it doesn't matter anymore which of your subclasses is currently active to get your data.

    @Christian-Ehrlicher
    I guess a good C++ book would be sufficient. He doesn't need to learn from a C++ god :D ;-)


  • Lifetime Qt Champion

    @Pl45m4 Thx, fixed :)


Log in to reply