Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved]Call class function in another cpp file

[solved]Call class function in another cpp file

Scheduled Pinned Locked Moved General and Desktop
classheadercppobjects
16 Posts 3 Posters 12.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • JohanSoloJ JohanSolo

    Well, as you discovered, you need an object to call a method. Then the most obvious solution would be to give a pointer on your MainWindow object to the function which tries to call MainWindow::test().

    One solution would be to emit a signal in your jsfunction,cpp (about which you don't give information) which would trigger the call to MainWindow::test() (which would need to be a slot). But without knowing what the content of jsfunction.cpp it's hard to tell.

    Give us more information on how you want to call MainWindow::test() and we'll be able to help.

    T Offline
    T Offline
    TheHawk
    wrote on last edited by TheHawk
    #4

    @JohanSolo @jsulm

    Currently I am working in 2 windows. 1 window is the MainWindow, the application launches with only this. The second window opens when requested and gives the functionality to parse a script (using QJSEngine). This window is called CustomCode.

    In the script I want to call functions which I have in my project. Currently I am only trying to call test() to understand the principle and continue from that.

    According to this stackoverflow, I had to use QObjects. That is where jsfunctions came in, this is a QObject class which I integrate into the QJSEngine.

    So my QS Script looks like this: jsfunction.call_test();

    CustomCode.h:

    #ifndef CUSTOMCODE_H
    #define CUSTOMCODE_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class CustomCode;
    }
    
    class CustomCode : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit CustomCode(QWidget *parent = 0);
        ~CustomCode();
    
    private:
        Ui::CustomCode *ui;
    
    private slots:
        void on_button_clicked();
    };
    
    #endif // CUSTOMCODE_H
    

    CustomCode.cpp:

    #include "customcode.h"
    #include "ui_customcode.h"
    #include "jsfunctions.h"
    #include <QtWidgets>
    #include <QJSEngine>
    #include <QFile>
    
    CustomCode::CustomCode(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::CustomCode)
    {
        ui->setupUi(this);
        QPushButton *button = new QPushButton("Test");
        ui->verticalLayout->addWidget(button);
        connect(button,SIGNAL(pressed()),SLOT(on_button_clicked()));
    
    }
    
    CustomCode::~CustomCode()
    {
        delete ui;
    }
    
    void CustomCode::on_button_clicked()
    {
        QLabel *tb = new QLabel;
        ui->verticalLayout->addWidget(tb);
        QJSEngine myEngine;
        QJSValue scripttb = myEngine.newQObject(tb);
        jsfunctions jsfunction;
        QJSValue jsfunctionObj = myEngine.newQObject(&jsfunction);
        myEngine.globalObject().setProperty("jsfunction",jsfunctionObj);
        myEngine.globalObject().setProperty("tb",scripttb);
    
        QString fileName = "customlogic.qs";
        QFile scriptFile(fileName);
        if (!scriptFile.open(QIODevice::ReadOnly))
        {
        }// handle error
    
        QTextStream stream(&scriptFile);
        QString contents = stream.readAll();
        scriptFile.close();
        QJSValue result = myEngine.evaluate(contents, fileName);
        //QJSValue result = myEngine.evaluate("jsfunction.call_test();");
        if (result.isError())
        {
            qDebug() << "result: " << result.property("lineNumber").toInt() << ":" << result.toString();
        }
    }
    

    jsfunctions.h:

    #ifndef JSFUNCTIONS_H
    #define JSFUNCTIONS_H
    
    #include <QObject>
    #include <QWidget>
    #include <mainwindow.h>
    
    class jsfunctions : public QObject
    {
        Q_OBJECT
    public:
        explicit jsfunctions(QObject *parent = 0);
        void call_test()
        {
            emit send_test();
        }
    
    
    signals:
        void send_test();
    
    public slots:
    
    };
    
    #endif // JSFUNCTIONS_H
    

    jsfunctions.cpp:

    #include "jsfunctions.h"
    #include "mainwindow.h"
    
    
    jsfunctions::jsfunctions(QObject *parent) : QObject(parent)
    {
    
    }
    

    MainWindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QtCore>
    #include <QtGui>
    #include <QProgressBar>
    #include <QGridLayout>
    #include <QScrollArea>
    #include "vprParam.h"
    #include "customcode.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        CustomCode *codewindow;
        ~MainWindow();
    
    public slots:
        void test();
    
    private:
        QStandardItemModel *model;
        QWidget *box;
        QGridLayout *grid;
        void build_UI(vprParam_Inst_t* pInst, std::string profile);
    
    private slots:
        void on_actionOpen_CSV_triggered();
        void on_actionIP_List_toggled(bool arg1);
    
        void on_treeView_doubleClicked(const QModelIndex &index);
    
        void on_actionSave_triggered();
    
        void on_profile_clicked(int index);
    
        void on_actionAdd_custom_logic_triggered();
    
    private:
        Ui::MainWindow *ui;
        QProgressBar *progressBar;
        QWidget *central;
        QGridLayout *layout;
    };
    
    void loadcsv(QString IP, QString SUBIP);
    void SetValueInDb(QString name, int value);
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp (only the relevant code)

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "vprParam.h"
    #include <string>
    #include <vector>
    #include <QFileDialog>
    #include <QtWidgets>
    #include <QComboBox>
    #include <QLabel>
    #include "paramblock.h"
    
    struct readips
    {
    };
    
    struct create_db
    {
    };
    
    struct memory
    {
    }
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        progressBar = new QProgressBar;
        ui->statusBar->addPermanentWidget(progressBar);
        progressBar->setVisible(false);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_actionOpen_CSV_triggered()
    {
    }
    
    
    void loadcsv(QString IP,QString SUBIP)
    {
    
    }
    
    void MainWindow::on_actionIP_List_toggled(bool arg1)
    {
    }
    
    
    void MainWindow::on_treeView_doubleClicked(const QModelIndex &index)
    {
        
    }
    
    void MainWindow::on_profile_clicked(int index)
    {
    }
    
    void MainWindow::build_UI(vprParam_Inst_t* pInst, std::string profile)
    {
    }
    
    void MainWindow::on_actionAdd_custom_logic_triggered()
    {
        codewindow = new CustomCode;
        codewindow->show();
    }
    
    void MainWindow::test()
    {
        progressBar->setEnabled(true);
        progressBar->setVisible(true);
        progressBar->setValue(50);
        ui->dockWidget->setWindowTitle("TEST");
    }
    

    I already tried to make it with signal/slots but I failed at this, I always ended up with having to create a new object for mainwindow, I would like to see how to do it properly.
    Also, sorry for any messy/confusing code, I am new to c++ and Qt and a rookie programmer overall.

    Thanks!

    1 Reply Last reply
    0
    • JohanSoloJ Offline
      JohanSoloJ Offline
      JohanSolo
      wrote on last edited by
      #5

      OK, according to what I understood from your design, MainWindow spawns a CustomCode instance when requested. Therefore when constructing the CustomCode instance you know which MainWindow instance you have to connect to. If I were you I'd use the calling MainWindow instance as parent of the CustomCode instance. This would allow to connect the send_test() signal to the test() slot of your MainWindow instance.

      `They did not know it was impossible, so they did it.'
      -- Mark Twain

      1 Reply Last reply
      1
      • T Offline
        T Offline
        TheHawk
        wrote on last edited by TheHawk
        #6

        How could I do that?

        If I do this in mainwindow.cpp:

            codewindow = new CustomCode;
            codewindow->setParent(this);
            connect(codewindow,SIGNAL(send_test()),SLOT(test()));
            codewindow->show();
        

        This makes it compile but instead of a seperate window the current mainwindow gets overwritten with the codewindow and the send_test() is in jsfunctions.h, not in CustomCode.h. Would I have to make a function that calls another function that calls the signal? Or am I missing it here? Sorry

        Edit:

        Succes!

        I used : (in mainwindow.cpp)

        void MainWindow::on_actionAdd_custom_logic_triggered()
        {
            codewindow = new CustomCode;
            QObject::connect(&jsfunction,SIGNAL(send_test()),this,SLOT(test()));
            codewindow->show();
        }
        

        added extern jsfunctions jsfunction; to mainwindow.h and customcode.h
        added jsfunctions jsfunction; in jsfunctions.cpp

        and changed jsfunctions.h to

        signals:
            void send_test();
        
        public slots:
            void call_test()
            {
                emit send_test();
            }
        

        Now it works! test() gets properly called and my UI actually changes. Many thanks! :)

        PS: How do I change the topic to solved?

        JohanSoloJ 1 Reply Last reply
        0
        • T TheHawk

          How could I do that?

          If I do this in mainwindow.cpp:

              codewindow = new CustomCode;
              codewindow->setParent(this);
              connect(codewindow,SIGNAL(send_test()),SLOT(test()));
              codewindow->show();
          

          This makes it compile but instead of a seperate window the current mainwindow gets overwritten with the codewindow and the send_test() is in jsfunctions.h, not in CustomCode.h. Would I have to make a function that calls another function that calls the signal? Or am I missing it here? Sorry

          Edit:

          Succes!

          I used : (in mainwindow.cpp)

          void MainWindow::on_actionAdd_custom_logic_triggered()
          {
              codewindow = new CustomCode;
              QObject::connect(&jsfunction,SIGNAL(send_test()),this,SLOT(test()));
              codewindow->show();
          }
          

          added extern jsfunctions jsfunction; to mainwindow.h and customcode.h
          added jsfunctions jsfunction; in jsfunctions.cpp

          and changed jsfunctions.h to

          signals:
              void send_test();
          
          public slots:
              void call_test()
              {
                  emit send_test();
              }
          

          Now it works! test() gets properly called and my UI actually changes. Many thanks! :)

          PS: How do I change the topic to solved?

          JohanSoloJ Offline
          JohanSoloJ Offline
          JohanSolo
          wrote on last edited by
          #7

          I don't think it is necessary to have a static instance of jsfunctions to do this. Why did you add it? As far as I understand, the jsfunctions instance was meant to be used in the CustomCode instance? Assuming my hypothesis is correct, I would do the connect in the CustomCode, where both the MainWindow and jsfunctions instance are used:

          void MainWindow::on_actionAdd_custom_logic_triggered()
          {
              codewindow = new CustomCode( this );
              codewindow->show();
          }
          
          CustomCode::CustomCode( QObject* parent )
              : QMainWindow(parent)
              , ui(new Ui::CustomCode)
              , jsfunction( new jsfunctions() )
          {
              connect( jsfunction, SIGNAL( send_test() ), parent, SLOT( test() ) );
          }
          
          @TheHawk said:
          > PS: How do I change the topic to solved?
          
          You can simply edit the topic title (IIRC by editing your first post),

          `They did not know it was impossible, so they did it.'
          -- Mark Twain

          1 Reply Last reply
          1
          • T Offline
            T Offline
            TheHawk
            wrote on last edited by
            #8

            I have no particular reason why I chose it to be static, I did it because after googling some errors it was suggested to use static.

            Anyhow, your code indeed works as well and your assumption was correct! :)
            I do have a little issue now. Calling codewindow = new CustomCode( this ); makes the new window always on top. I previously called codewindow = new CustomCode;, this made the 2 windows independant (if you clicked the one in the back it came to front). I don't really see an option how to fix this behavior besides using signals and slots at a click to bring a window up and lower the other one. Am I missing the obvious here?

            thanks!

            1 Reply Last reply
            0
            • JohanSoloJ Offline
              JohanSoloJ Offline
              JohanSolo
              wrote on last edited by JohanSolo
              #9

              I think you can tune this behaviour with the correct window flag, which is the second argument of the QMainWindow constructor.

              Edit:
              As another way to do it, you can pass a null pointer to the QMainWindow constructor in the CustomCode constructor, but still use the parent pointer in the connect statement.

              `They did not know it was impossible, so they did it.'
              -- Mark Twain

              1 Reply Last reply
              0
              • T Offline
                T Offline
                TheHawk
                wrote on last edited by
                #10

                I tried all the window flag settings without succes, it always stays on top.

                How would I pass a null pointer to the QMainWindow constructor in the CustomCode constructor? Can't really get my head around it. Changing the call to:
                codewindow = new CustomCode(0); or codewindow = new CustomCode; creates the desired effect but makes me unable to call the function (since no parent exists I think?).

                Am I even calling the windowflag correctly?

                void MainWindow::on_actionAdd_custom_logic_triggered()
                {
                    CustomCode *codewindow;
                    codewindow = new CustomCode(0);
                    //QObject::connect(&jsfunction,SIGNAL(send_test()),this,SLOT(test()));
                    codewindow->setWindowFlags(Qt::Window);
                    codewindow->show();
                
                }
                
                1 Reply Last reply
                0
                • JohanSoloJ Offline
                  JohanSoloJ Offline
                  JohanSolo
                  wrote on last edited by
                  #11

                  I was thinking about

                  CustomCode::CustomCode( QObject* parent )
                      : QMainWindow( 0 )
                      , ui( new Ui::CustomCode )
                      , jsfunction( new jsfunctions() )
                  {
                      connect( jsfunction, SIGNAL( send_test() ), parent, SLOT( test() ) );
                  }
                  

                  `They did not know it was impossible, so they did it.'
                  -- Mark Twain

                  T 1 Reply Last reply
                  1
                  • JohanSoloJ JohanSolo

                    I was thinking about

                    CustomCode::CustomCode( QObject* parent )
                        : QMainWindow( 0 )
                        , ui( new Ui::CustomCode )
                        , jsfunction( new jsfunctions() )
                    {
                        connect( jsfunction, SIGNAL( send_test() ), parent, SLOT( test() ) );
                    }
                    
                    T Offline
                    T Offline
                    TheHawk
                    wrote on last edited by
                    #12

                    @JohanSolo

                    Ah yes, seems so obvious now. Works like a charm!

                    Thanks :)

                    1 Reply Last reply
                    0
                    • JohanSoloJ Offline
                      JohanSoloJ Offline
                      JohanSolo
                      wrote on last edited by
                      #13

                      You're welcome! I'm glad I could help.

                      `They did not know it was impossible, so they did it.'
                      -- Mark Twain

                      T 1 Reply Last reply
                      1
                      • JohanSoloJ JohanSolo

                        You're welcome! I'm glad I could help.

                        T Offline
                        T Offline
                        TheHawk
                        wrote on last edited by
                        #14

                        @JohanSolo

                        I got a question though (kinda off-topic). Would it be possible to create a signal from the MainWindow to a slot (or function) inside the javascript script that I evaluate inside CustomCode? So for example:

                        I want to plot a graph using the javascript script. I want that graph to use actual, changing values from mainwindow. So I would like to create a signal that triggers upon a value change and then call a function inside the javascript script to update the graph with the new values.

                        1 Reply Last reply
                        0
                        • JohanSoloJ Offline
                          JohanSoloJ Offline
                          JohanSolo
                          wrote on last edited by
                          #15

                          @TheHawk said:

                          I got a question though (kinda off-topic). Would it be possible to create a signal from the MainWindow to a slot (or function) inside the javascript script that I evaluate inside CustomCode? So for example:

                          Better ask a new question in a new thread, for the future, it helps when looking for a problem on the forum.

                          You are free to define any signal / slot you want, so the short answer is yes.
                          You can emit a signal in MainWindowwhen the data needs to be reprocessed by the js script managed by CustomCode.

                          `They did not know it was impossible, so they did it.'
                          -- Mark Twain

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            TheHawk
                            wrote on last edited by
                            #16

                            My apologies, I will create a new thread. Thanks for all your help! (and putting up with my stuff :) )

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved