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. Accessing MainWindow object from another class
Forum Updated to NodeBB v4.3 + New Features

Accessing MainWindow object from another class

Scheduled Pinned Locked Moved Unsolved General and Desktop
signals & slotswidget
15 Posts 5 Posters 9.0k 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.
  • Q Offline
    Q Offline
    qt.1234
    wrote on last edited by qt.1234
    #6

    Hi, not sure if i got your question right. But you can follow the example below. In TestClass.h you have to first declare the signal testClassSignal(). so whenever the signal is invoked in testClass.cpp, the slot in MainWindow.cpp called testClassSlot will be invoked in MainWindow.cpp. I hope it helps.

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui:MainWindow)
    {
     TestClass * testClass = new TestClass();
    initConnections();
    }
    
    void MainWindow::initConnections()
    {
    QObject::connect(testClass, SIGNAL(testClassSignal()), this, SLOT(testClassSlot()),Qt::AutoConnection);
    }
    
    void MainWindow::testClassSlot()
    {
    
    }
    
    void TestClass::TestClass()
    {
    
    }
    
    
    1 Reply Last reply
    1
    • T TUStudi

      Hey,

      If I want to create a Qt widget application, I have my MainWindow.ui, MainWindow.cpp and MainWindow.cpp. Assuming I have another class called TestClass in which I want to call a slot that is implemented the MainWindow class, how can I access the MainWindow Object, which is normally created in main.cpp? If

      For Example:

      void TestClass::startDeviceDiscovery(){
          discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
          discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
          connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, &MainWindowObject, &MainWindow::deviceDiscovered); //deviceDiscovered is my Slot implemented in MainWindow.cpp
          discoveryAgent->start();
      }
      
      

      So what would be my &MainWindowObject? My main:

      #include "MainWindow.h"
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          MainWindow w;
          w.show();
          return a.exec();
      
      }
      

      So if I create the MainWindow Object outside the main function I cannot use it in my TestClass because I cannot include main there. What is the best way to solve my problem?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #7

      @TUStudi
      Is TestClass just for testing? Otherwise the more usual pattern is not to access MainWindow from other classes, but rather the other way round. Have MainWindow do the connect of the TestClass signal to its own slot.

      1 Reply Last reply
      0
      • jsulmJ jsulm

        @TUStudi For testing I suggest you take a look at: https://doc.qt.io/qt-5/qtest-overview.html
        For testing you do not have to create your main window inside main.

        T Offline
        T Offline
        TUStudi
        wrote on last edited by TUStudi
        #8

        @jsulm said in Accessing MainWindow object from another class:

        @TUStudi For testing I suggest you take a look at: https://doc.qt.io/qt-5/qtest-overview.html
        For testing you do not have to create your main window inside main.

        Thank you, but it is not a class for testing, it is just a andom class name ;)

        @qt-1234 said in Accessing MainWindow object from another class:

        Hi, not sure if i got your question right. But you can follow the example below. In TestClass.h you have to first declare the signal testClassSignal(). so whenever the signal is invoked in testClass.cpp, the slot in MainWindow.cpp called testClassSlot will be invoked in MainWindow.cpp. I hope it helps.

        MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui:MainWindow)
        {
         TestClass * testClass = new TestClass();
        initConnections();
        }
        
        void MainWindow::initConnections()
        {
        QObject::connect(testClass, SIGNAL(testClassSignal()), this, SLOT(testClassSlot()),Qt::AutoConnection);
        }
        
        void MainWindow::testClassSlot()
        {
        
        }
        
        void TestClass::TestClass()
        {
        
        }
        
        

        Thank you tu @qt-1234. In my case, the Signal is not emitted by the Testclass but by an object of &QBluetoothDeviceDiscoveryAgent and the Signal is the &QBluetoothDeviceDiscoveryAgent::deviceDiscovered it is emitted every time a new Bluetooth device is discovered. So that won't work, will it?

        connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, MainWindowObject, MainWindowSlot);
        
        jsulmJ JonBJ Q 3 Replies Last reply
        0
        • T TUStudi

          @jsulm said in Accessing MainWindow object from another class:

          @TUStudi For testing I suggest you take a look at: https://doc.qt.io/qt-5/qtest-overview.html
          For testing you do not have to create your main window inside main.

          Thank you, but it is not a class for testing, it is just a andom class name ;)

          @qt-1234 said in Accessing MainWindow object from another class:

          Hi, not sure if i got your question right. But you can follow the example below. In TestClass.h you have to first declare the signal testClassSignal(). so whenever the signal is invoked in testClass.cpp, the slot in MainWindow.cpp called testClassSlot will be invoked in MainWindow.cpp. I hope it helps.

          MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui:MainWindow)
          {
           TestClass * testClass = new TestClass();
          initConnections();
          }
          
          void MainWindow::initConnections()
          {
          QObject::connect(testClass, SIGNAL(testClassSignal()), this, SLOT(testClassSlot()),Qt::AutoConnection);
          }
          
          void MainWindow::testClassSlot()
          {
          
          }
          
          void TestClass::TestClass()
          {
          
          }
          
          

          Thank you tu @qt-1234. In my case, the Signal is not emitted by the Testclass but by an object of &QBluetoothDeviceDiscoveryAgent and the Signal is the &QBluetoothDeviceDiscoveryAgent::deviceDiscovered it is emitted every time a new Bluetooth device is discovered. So that won't work, will it?

          connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, MainWindowObject, MainWindowSlot);
          
          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #9

          @TUStudi said in Accessing MainWindow object from another class:

          So that won't work, will it?

          It should. Did you try?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • T TUStudi

            @jsulm said in Accessing MainWindow object from another class:

            @TUStudi For testing I suggest you take a look at: https://doc.qt.io/qt-5/qtest-overview.html
            For testing you do not have to create your main window inside main.

            Thank you, but it is not a class for testing, it is just a andom class name ;)

            @qt-1234 said in Accessing MainWindow object from another class:

            Hi, not sure if i got your question right. But you can follow the example below. In TestClass.h you have to first declare the signal testClassSignal(). so whenever the signal is invoked in testClass.cpp, the slot in MainWindow.cpp called testClassSlot will be invoked in MainWindow.cpp. I hope it helps.

            MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui:MainWindow)
            {
             TestClass * testClass = new TestClass();
            initConnections();
            }
            
            void MainWindow::initConnections()
            {
            QObject::connect(testClass, SIGNAL(testClassSignal()), this, SLOT(testClassSlot()),Qt::AutoConnection);
            }
            
            void MainWindow::testClassSlot()
            {
            
            }
            
            void TestClass::TestClass()
            {
            
            }
            
            

            Thank you tu @qt-1234. In my case, the Signal is not emitted by the Testclass but by an object of &QBluetoothDeviceDiscoveryAgent and the Signal is the &QBluetoothDeviceDiscoveryAgent::deviceDiscovered it is emitted every time a new Bluetooth device is discovered. So that won't work, will it?

            connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, MainWindowObject, MainWindowSlot);
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #10

            @TUStudi
            Maybe it's just me, but I still wouldn't connect to a MainWindow slot from any other class. EDIT To be clear, I would never #include mainwindow.h into TestClass, so there is no way the latter could access &MainWindow::deviceDiscovered.

            If you only ever create one instance of discoveryAgent once, make that exportable from TestClass to MainWindow so that the latter can do the connect on that one instance. If you create instances dynamically, invent a signal from TestClass passing the instance of QBluetoothDeviceDiscoveryAgent as an argument upon creation, and have MainWindow pick that up and put its slot on the instance's deviceDiscovered.

            That's how I would do it. If a Qt expert says I'm wrong, please let me know!

            @jsulm I'm not sure, but I think the OP is saying he can't do that connect from MainWindow because the instance is newed inside TestClass::startDeviceDiscovery()?

            T 1 Reply Last reply
            2
            • JonBJ JonB

              @TUStudi
              Maybe it's just me, but I still wouldn't connect to a MainWindow slot from any other class. EDIT To be clear, I would never #include mainwindow.h into TestClass, so there is no way the latter could access &MainWindow::deviceDiscovered.

              If you only ever create one instance of discoveryAgent once, make that exportable from TestClass to MainWindow so that the latter can do the connect on that one instance. If you create instances dynamically, invent a signal from TestClass passing the instance of QBluetoothDeviceDiscoveryAgent as an argument upon creation, and have MainWindow pick that up and put its slot on the instance's deviceDiscovered.

              That's how I would do it. If a Qt expert says I'm wrong, please let me know!

              @jsulm I'm not sure, but I think the OP is saying he can't do that connect from MainWindow because the instance is newed inside TestClass::startDeviceDiscovery()?

              T Offline
              T Offline
              TUStudi
              wrote on last edited by
              #11

              @JonB said in Accessing MainWindow object from another class:

              @TUStudi
              Maybe it's just me, but I still wouldn't connect to a MainWindow slot from any other class. EDIT To be clear, I would never #include mainwindow.h into TestClass, so there is no way the latter could access &MainWindow::deviceDiscovered.

              If you only ever create one instance of discoveryAgent once, make that exportable from TestClass to MainWindow so that the latter can do the connect on that one instance. If you create instances dynamically, invent a signal from TestClass passing the instance of QBluetoothDeviceDiscoveryAgent as an argument upon creation, and have MainWindow pick that up and put its slot on the instance's deviceDiscovered.

              That's how I would do it. If a Qt expert says I'm wrong, please let me know!

              @jsulm I'm not sure, but I think the OP is saying he can't do that connect from MainWindow because the instance is newed inside TestClass::startDeviceDiscovery()?

              Hello JonB,
              as I wrote in an other Thread, the idea of ​​mine is that I separate the actual logic from the UI. The communication should take place via my controller (my MainWindow.cpp). I.e. the user clicks on the "Scan for Bluetooth devices" button in the UI, this triggers a "button clicked" slot in my MainWindow.cpp. The startDeviceDiscovery method of the "TestClass" (which should contain the logic) is then called in this slot. If devices are then found, my MainWindow is notified by a signal (deviceDiscovered) and this MainWIndow interacts with the UI by entering the devices in the combo box.

              553828a0-c21f-406e-92d2-7b07d312184e-image.png

              But I just notice that a user in my other thread replied, which I unfortunately didn't see.

              Your MainWindow should have a member variable of the TestClass class.
              Your TestClass class should provide an API that your MainWindow can connect to and also that provides whatever data is needed.

              So, do you know how to do that? I thought my problem can be solved If I just make my MainWIndow Object, which is created in my main class, globally.
              But it seems I haven't understood the principle of OOP.

              JonBJ 1 Reply Last reply
              0
              • T TUStudi

                @JonB said in Accessing MainWindow object from another class:

                @TUStudi
                Maybe it's just me, but I still wouldn't connect to a MainWindow slot from any other class. EDIT To be clear, I would never #include mainwindow.h into TestClass, so there is no way the latter could access &MainWindow::deviceDiscovered.

                If you only ever create one instance of discoveryAgent once, make that exportable from TestClass to MainWindow so that the latter can do the connect on that one instance. If you create instances dynamically, invent a signal from TestClass passing the instance of QBluetoothDeviceDiscoveryAgent as an argument upon creation, and have MainWindow pick that up and put its slot on the instance's deviceDiscovered.

                That's how I would do it. If a Qt expert says I'm wrong, please let me know!

                @jsulm I'm not sure, but I think the OP is saying he can't do that connect from MainWindow because the instance is newed inside TestClass::startDeviceDiscovery()?

                Hello JonB,
                as I wrote in an other Thread, the idea of ​​mine is that I separate the actual logic from the UI. The communication should take place via my controller (my MainWindow.cpp). I.e. the user clicks on the "Scan for Bluetooth devices" button in the UI, this triggers a "button clicked" slot in my MainWindow.cpp. The startDeviceDiscovery method of the "TestClass" (which should contain the logic) is then called in this slot. If devices are then found, my MainWindow is notified by a signal (deviceDiscovered) and this MainWIndow interacts with the UI by entering the devices in the combo box.

                553828a0-c21f-406e-92d2-7b07d312184e-image.png

                But I just notice that a user in my other thread replied, which I unfortunately didn't see.

                Your MainWindow should have a member variable of the TestClass class.
                Your TestClass class should provide an API that your MainWindow can connect to and also that provides whatever data is needed.

                So, do you know how to do that? I thought my problem can be solved If I just make my MainWIndow Object, which is created in my main class, globally.
                But it seems I haven't understood the principle of OOP.

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #12

                @TUStudi said in Accessing MainWindow object from another class:

                I thought my problem can be solved If I just make my MainWIndow Object, which is created in my main class, globally.

                I just would not do this. Make MainWindow know about the other classes, and have it do the connect()s, rather than having the other classes know about MainWindow and they do the connect(). Or, just possibly, put your "controller" class elsewhere than in MainWindow.

                T 1 Reply Last reply
                4
                • T TUStudi

                  @jsulm said in Accessing MainWindow object from another class:

                  @TUStudi For testing I suggest you take a look at: https://doc.qt.io/qt-5/qtest-overview.html
                  For testing you do not have to create your main window inside main.

                  Thank you, but it is not a class for testing, it is just a andom class name ;)

                  @qt-1234 said in Accessing MainWindow object from another class:

                  Hi, not sure if i got your question right. But you can follow the example below. In TestClass.h you have to first declare the signal testClassSignal(). so whenever the signal is invoked in testClass.cpp, the slot in MainWindow.cpp called testClassSlot will be invoked in MainWindow.cpp. I hope it helps.

                  MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui( new Ui:MainWindow)
                  {
                   TestClass * testClass = new TestClass();
                  initConnections();
                  }
                  
                  void MainWindow::initConnections()
                  {
                  QObject::connect(testClass, SIGNAL(testClassSignal()), this, SLOT(testClassSlot()),Qt::AutoConnection);
                  }
                  
                  void MainWindow::testClassSlot()
                  {
                  
                  }
                  
                  void TestClass::TestClass()
                  {
                  
                  }
                  
                  

                  Thank you tu @qt-1234. In my case, the Signal is not emitted by the Testclass but by an object of &QBluetoothDeviceDiscoveryAgent and the Signal is the &QBluetoothDeviceDiscoveryAgent::deviceDiscovered it is emitted every time a new Bluetooth device is discovered. So that won't work, will it?

                  connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, MainWindowObject, MainWindowSlot);
                  
                  Q Offline
                  Q Offline
                  qt.1234
                  wrote on last edited by
                  #13

                  @TUStudi Hi. Then you will have to first initialize the discoveryAgent class first just like how i did for the testClass before doing the connection of signal and slot.

                  DiscoveryAgent * discoveryAgent = new DiscoveryAgent();
                  
                  1 Reply Last reply
                  0
                  • JonBJ JonB

                    @TUStudi said in Accessing MainWindow object from another class:

                    I thought my problem can be solved If I just make my MainWIndow Object, which is created in my main class, globally.

                    I just would not do this. Make MainWindow know about the other classes, and have it do the connect()s, rather than having the other classes know about MainWindow and they do the connect(). Or, just possibly, put your "controller" class elsewhere than in MainWindow.

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

                    @JonB said in Accessing MainWindow object from another class:

                    I just would not do this. Make MainWindow know about the other classes, and have it do the connect()s, rather than having the other classes know about MainWindow and they do the connect(). Or, just possibly, put your "controller" class elsewhere than in MainWindow.

                    Thank you, here is my approach and it seems to work. I created a new Slot in my TestClass that is called, when a device is discovered. Then, in this Slot I emitted a Signal with the devicename that is then received by my mainwindow and mainwindow then does the work. Thus, my TestClass does not know anything about my MainWindow.

                    void TestClass::startDeviceDiscovery(){
                        discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
                        discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
                        connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &TestClass::deviceDiscoveredSlot);
                        discoveryAgent->start();
                    }
                    
                    void TestClass::deviceDiscoveredSlot(const QBluetoothDeviceInfo &device)
                    {
                        emit deviceDiscoveredSignal(device);
                    }
                    
                    

                    And in my MainWindow Class:

                    MainWindow::MainWindow(QWidget *parent)
                        : QMainWindow(parent)
                        , ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                        connect(bluetoothModel, &BluetoothModel::deviceDiscoveredSignal, this, &BluetoothController::deviceDiscovered);
                    }
                    
                    
                    void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
                    {
                        ui->devicesList->addItem(device.name());
                    }
                    
                    

                    The only annoying thing is that I have more code with it because I can't call a slot from MainWindow directly. But it works.

                    JonBJ 1 Reply Last reply
                    1
                    • T TUStudi

                      @JonB said in Accessing MainWindow object from another class:

                      I just would not do this. Make MainWindow know about the other classes, and have it do the connect()s, rather than having the other classes know about MainWindow and they do the connect(). Or, just possibly, put your "controller" class elsewhere than in MainWindow.

                      Thank you, here is my approach and it seems to work. I created a new Slot in my TestClass that is called, when a device is discovered. Then, in this Slot I emitted a Signal with the devicename that is then received by my mainwindow and mainwindow then does the work. Thus, my TestClass does not know anything about my MainWindow.

                      void TestClass::startDeviceDiscovery(){
                          discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
                          discoveryAgent->setLowEnergyDiscoveryTimeout(5000);
                          connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &TestClass::deviceDiscoveredSlot);
                          discoveryAgent->start();
                      }
                      
                      void TestClass::deviceDiscoveredSlot(const QBluetoothDeviceInfo &device)
                      {
                          emit deviceDiscoveredSignal(device);
                      }
                      
                      

                      And in my MainWindow Class:

                      MainWindow::MainWindow(QWidget *parent)
                          : QMainWindow(parent)
                          , ui(new Ui::MainWindow)
                      {
                          ui->setupUi(this);
                          connect(bluetoothModel, &BluetoothModel::deviceDiscoveredSignal, this, &BluetoothController::deviceDiscovered);
                      }
                      
                      
                      void MainWindow::deviceDiscovered(const QBluetoothDeviceInfo &device)
                      {
                          ui->devicesList->addItem(device.name());
                      }
                      
                      

                      The only annoying thing is that I have more code with it because I can't call a slot from MainWindow directly. But it works.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #15

                      @TUStudi
                      I do believe this is the neater way to go. Your MainWindow and your TestClass are now quite independent of each other. If you had done "call a slot from MainWindow directly" TestClass would not be (re-)usable without MainWindow.

                      1 Reply Last reply
                      1

                      • Login

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