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 widgets from my class

Accessing widgets from my class

Scheduled Pinned Locked Moved General and Desktop
29 Posts 3 Posters 11.5k 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.
  • F Offline
    F Offline
    Flurite
    wrote on last edited by
    #1

    Hi,

    I've been working on a timer application, but have run into trouble when converting it to a Qt Widget Application. As it is right, now, I decided to make my own Stopwatch class, and the basic framework of it is as following:

    @
    class Stopwatch : public QObject
    {
    Q_OBJECT
    private:
    QTimer* timer;
    public:
    Stopwatch()
    {
    connect(timer, SIGNAL(timeout()), this, SLOT(changeTime()));
    }
    private slots:
    void changeTime();
    };

    void Stopwatch::changeTime()
    {
    /* code (parts try to access the widgets) */
    }
    @

    A problem with this is that I cannot access widgets from the class, because I have not declared a pointer to the MainWindow, which is called "Clock_Application" in this program. I tried declaring a pointer to Clock_Application by adding it to the private members of my class:

    @
    private:
    QTimer* timer;
    Clock_Application* ui;
    @

    But then it complains that Output(a lineEdit in my widget) does not exist, which it obviously does, because in my previous widget application (it was laggy, so I am revise it), Output was there.

    So any solutions to accessing my widgets from my class function?

    1 Reply Last reply
    0
    • M Offline
      M Offline
      MuldeR
      wrote on last edited by
      #2

      I think your Stopwatch class shouldn't have to know about Clock_Application.

      Let's assume your Stopwatch class wants to write something to a QLabel widget on a timer event, then make it as general as possible and just store a pointer to a QLabel that is set in the constructor:

      @ class Stopwatch : public QObject
      {
      Q_OBJECT
      private:
      QTimer* m_timer;
      QLabel* m_label;
      public:
      Stopwatch(QLabel* label)
      {
      m_timer = new QTimer(); //haven't you forgot this ???
      m_label = label; //remember pointer for later use!
      connect(m_timer, SIGNAL(timeout()), this, SLOT(changeTime()));
      }
      ~Stopwatch(void)
      {
      delete m_timer;
      }
      private slots:
      void changeTime();
      };

      void Stopwatch::changeTime()
      {
          m_label->doSomething();
      }
      

      @

      My OpenSource software at: http://muldersoft.com/

      Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

      Go visit the coop: http://youtu.be/Jay...

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Flurite
        wrote on last edited by
        #3

        [quote author="MuldeR" date="1335142286"]I think your Stopwatch class shouldn't have to know about Clock_Application.

        Let's assume your Stopwatch class wants to write something to a QLabel widget on a timer event, then make it as general as possible and just store a pointer to a QLabel that is set in the constructor:

        @ class Stopwatch : public QObject
        {
        Q_OBJECT
        private:
        QTimer* m_timer;
        QLabel* m_label;
        public:
        Stopwatch(QLabel* label)
        {
        m_timer = new QTimer(); //haven't you forgot this ???
        m_label = label; //remember pointer for later use!
        connect(m_timer, SIGNAL(timeout()), this, SLOT(changeTime()));
        }
        ~Stopwatch(void)
        {
        delete m_timer;
        }
        private slots:
        void changeTime();
        };

        void Stopwatch::changeTime()
        {
            m_label->doSomething();
        }
        

        @[/quote]

        Thanks for the response.

        One last question though. Where would I create a new instance of Stopwatch though? To store the GUI as a parameter, I would have to be able to access the widget. Is this right? If so, is there a work around?

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MuldeR
          wrote on last edited by
          #4

          well, usually your application will look something like:
          @main()
          {
          QApplication app(argc, argv);
          mainWindow = new MyMainWindow();
          mainWindow->show();
          int ret = app.exec();
          delete mainWindow;
          return ret;
          }@

          And your MyMainWindow class may look like:
          @class MyMainWindow: public QMainWindow, private Ui::MyMainWindow
          {
          Q_OBJECT

          public:
          MyMainWindow(QWidget *parent = 0);
          ~MyMainWindow(void);
          private:
          m_stopwatch *Stopwatch; //member variable to store the Stopwatch pointer

          ....
          

          }@

          In the constructor of MyMainWindow you would set up everything:
          @MyMainWindow::MyMainWindow(QWidget *parent)
          {
          //Init the dialog, from the .ui file
          setupUi(this);

          //Create the Stopwatch object and pass the pointer to our QLabel!
          m_stopwatch = new Stopwatch(myLabel);
          
          ....
          

          }@

          Don't forget the clean-up:
          @MyMainWindow::~MyMainWindow(void)
          {
          delete m_stopwatch;
          }@

          Note: The code above assumes that there is QLabel "myLabel" in the .ui file!

          My OpenSource software at: http://muldersoft.com/

          Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

          Go visit the coop: http://youtu.be/Jay...

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mlong
            wrote on last edited by
            #5

            Actually, there's probably no real reason to break the QTimer functionality into its own Stopwatch class, if it's supposed to just be updating the label in your MainWindow. In that case, just create a QTimer which is a member of MainWindow and set up a private slot in MainWindow which will get called when the timer fires.

            Since your label widget should be visible from within MainWindow, then you shouldn't have any problems updating it from a slot in MainWindow.

            Software Engineer
            My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

            1 Reply Last reply
            0
            • F Offline
              F Offline
              Flurite
              wrote on last edited by
              #6

              [quote author="mlong" date="1335210337"]Actually, there's probably no real reason to break the QTimer functionality into its own Stopwatch class, if it's supposed to just be updating the label in your MainWindow. In that case, just create a QTimer which is a member of MainWindow and set up a private slot in MainWindow which will get called when the timer fires.

              Since your label widget should be visible from within MainWindow, then you shouldn't have any problems updating it from a slot in MainWindow.
              [/quote]

              I've tried that idea before, but unfortunately it gives me this error, which I have absolutely no idea why it does give it to me:

              invalid use of incomplete struct type 'struct Ui::Clock_Application'
              forward declaration of 'struct Ui::Clock_Application'

              [quote author="MuldeR" date="1335210138"]well, usually your application will look something like:
              @main()
              {
              QApplication app(argc, argv);
              mainWindow = new MyMainWindow();
              mainWindow->show();
              int ret = app.exec();
              delete mainWindow;
              return ret;
              }@

              And your MyMainWindow class may look like:
              @class MyMainWindow: public QMainWindow, private Ui::MyMainWindow
              {
              Q_OBJECT

              public:
              MyMainWindow(QWidget *parent = 0);
              ~MyMainWindow(void);
              private:
              m_stopwatch *Stopwatch; //member variable to store the Stopwatch pointer

              ....
              

              }@

              In the constructor of MyMainWindow you would set up everything:
              @MyMainWindow::MyMainWindow(QWidget *parent)
              {
              //Init the dialog, from the .ui file
              setupUi(this);

              //Create the Stopwatch object and pass the pointer to our QLabel!
              m_stopwatch = new Stopwatch(myLabel);
              
              ....
              

              }@

              Don't forget the clean-up:
              @MyMainWindow::~MyMainWindow(void)
              {
              delete m_stopwatch;
              }@

              Note: The code above assumes that there is QLabel "myLabel" in the .ui file![/quote]

              I am running into problems everywhere. Somehow, it's complaining that I have multiple declarations in this piece of code:

              @class Clock_Application : public QMainWindow
              {
              Q_OBJECT

              public:
              explicit Clock_Application(QWidget parent = 0);
              ~Clock_Application();
              public slots:
              void timer_Start();
              private:
              Ui::Clock_Application ui;
              QTimer
              timer;
              Stopwatch
              stopwatchClass;
              };
              ///////////////////////////////////
              class Stopwatch : public QObject
              {
              Q_OBJECT
              private:
              QTimer* timer;
              QLineEdit* OutputToChange;
              public:
              Stopwatch(QLineEdit* output)
              {
              timer = new QTimer();
              OutputToChange = output;
              connect(timer, SIGNAL(timeout()), this, SLOT(changeTime(QLineEdit*)));
              }
              private slots:
              void changeTime(QLineEdit* output);
              };

              void Stopwatch::changeTime(QLineEdit* output)
              {
              /* code that tries to access widget */
              }
              @

              multiple definition of 'Stopwatch::changeTime(QLineEdit*)'
              first defined here

              This error happened twice.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                MuldeR
                wrote on last edited by
                #7

                Have you created a "Clock_Application.ui" file with QtDesigner?

                Also have you compiled the .ui file with UIC to get the corresponding include (.h) file?

                And have you included that .h file in the file where your Clock_Application class is declared?

                My OpenSource software at: http://muldersoft.com/

                Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                Go visit the coop: http://youtu.be/Jay...

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mlong
                  wrote on last edited by
                  #8

                  You can't connect timeout() to changeTime(QLineEdit*). The slot has to have the same (or fewer)
                  parameters than the signal.

                  Remember, the connect is just setting up a connection that will be called when some signal is emitted later on. How should timer's timeout() have any idea what to pass into the QLineEdit* parameter to changeTime?

                  Software Engineer
                  My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    mlong
                    wrote on last edited by
                    #9

                    [quote author="Flurite" date="1335214034"]
                    I’ve tried [adding a QTimer to the MainWindow's code] before, but unfortunately it gives me this error, which I have absolutely no idea why it does give it to me:
                    invalid use of incomplete struct type ‘struct Ui::Clock_Application’
                    forward declaration of ‘struct Ui::Clock_Application’
                    [/quote]

                    You should work on using the simplest model and fixing that particular error instead of trying to contrive an alternate solution which is, honestly, cumbersome and kludgy.

                    If you could post code on how you tried to use the in-class QTimer method, we can help you fix the error you mentioned.

                    Software Engineer
                    My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                    1 Reply Last reply
                    0
                    • F Offline
                      F Offline
                      Flurite
                      wrote on last edited by
                      #10

                      [quote author="mlong" date="1335215064"]
                      [quote author="Flurite" date="1335214034"]
                      I’ve tried [adding a QTimer to the MainWindow's code] before, but unfortunately it gives me this error, which I have absolutely no idea why it does give it to me:
                      invalid use of incomplete struct type ‘struct Ui::Clock_Application’
                      forward declaration of ‘struct Ui::Clock_Application’
                      [/quote]

                      You should work on using the simplest model and fixing that particular error instead of trying to contrive an alternate solution which is, honestly, cumbersome and kludgy.

                      If you could post code on how you tried to use the in-class QTimer method, we can help you fix the error you mentioned.[/quote]

                      I see.

                      This is what I am working with:

                      @
                      class Clock_Application : public QMainWindow
                      {
                      Q_OBJECT

                      public:
                      explicit Clock_Application(QWidget *parent = 0);
                      ~Clock_Application();
                      public slots:
                      void timer_Start();
                      void changeTime();
                      private:
                      Ui::Clock_Application ui;
                      QTimer
                      timer;
                      };

                      void Clock_Application::timer_Start()
                      {
                      timer = new QTimer();
                      connect(timer, SIGNAL(timeout()), this, SLOT(changeTime()));
                      timer->start(1000);
                      }

                      void Clock_Application::changeTime()
                      {
                      /* do you need to see this function? */
                      }
                      @

                      Take note that timer_start() is connected to an on-click signal. Also, I do not have anything to do with this in my .cpp files as I believe that these functions are controlled by the signals.

                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        MuldeR
                        wrote on last edited by
                        #11

                        This code excerpt looks okay to me.

                        Except that you should not create a new QTimer object every time timer_Start() is called. The function may be called several times. Better create the timer object once in the constructor of Clock_Application and destroy it in the destructor of Clock_Application. If you insist to create the QTimer object in timer_Start(), at least set the member variable 'timer' to NULL in the constructor and, if 'timer' is unequal NULL (i.e. an object has been created in a previous call to timer_Start()), destroy the "old" object before you create the new one. Even with the latter approach, remember to destroy the QTimer object, if any was created, in the destructor of Clock_Application...

                        Besides that, what exactly is your problem now?

                        My OpenSource software at: http://muldersoft.com/

                        Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                        Go visit the coop: http://youtu.be/Jay...

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          mlong
                          wrote on last edited by
                          #12

                          In
                          @
                          void Clock_Application::changeTime()
                          {
                          /* do you need to see this function? */
                          }
                          @

                          you should have something like:
                          @
                          void Clock_Application::changeTime()
                          {
                          QString value = "Whatever the label should be.";

                          ui->labelWidget->setText(value); // Use whatever you've called your QLabel here instead of "labelWidget"
                          }
                          @

                          It would probably be helpful to see both your changeTime() method and the Clock_Application constructor.

                          Software Engineer
                          My views and opinions do not necessarily reflect those of anyone -- living or dead, real or fictional -- in this universe or any other similar multiverse node. Void where prohibited. Your mileage may vary. Caveat emptor.

                          1 Reply Last reply
                          0
                          • F Offline
                            F Offline
                            Flurite
                            wrote on last edited by
                            #13

                            [quote author="MuldeR" date="1335219515"]This code excerpt looks okay to me.

                            Except that you should not create a new QTimer object every time timer_Start() is called. The function may be called several times. Better create the timer object once in the constructor of Clock_Application and destroy it in the destructor of Clock_Application. If you insist to create the QTimer object in timer_Start(), at least set the member variable 'timer' to NULL in the constructor and, if 'timer' is unequal NULL (i.e. an object has been created in a previous call to timer_Start()), destroy the "old" object before you create the new one. Even with the latter approach, remember to destroy the QTimer object, if any was created, in the destructor of Clock_Application...

                            Besides that, what exactly is your problem now?[/quote]

                            Thanks for the advice, I will surely take that into account. Anyhow, the errors were as mentioned in a previous post this:

                            invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 40
                            forward declaration of ‘struct Ui::Clock_Application’ --- at line 11
                            invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 73
                            forward declaration of ‘struct Ui::Clock_Application’ --- at line 11,

                            Lines 40 and 73 are lines in my changeValue() method that try and access the widget.. not surprising lol..

                            [quote author="mlong" date="1335219613"]In
                            @
                            void Clock_Application::changeTime()
                            {
                            /* do you need to see this function? */
                            }
                            @

                            you should have something like:
                            @
                            void Clock_Application::changeTime()
                            {
                            QString value = "Whatever the label should be.";

                            ui->labelWidget->setText(value); // Use whatever you've called your QLabel here instead of "labelWidget"
                            }
                            @

                            It would probably be helpful to see both your changeTime() method and the Clock_Application constructor.

                            [/quote]

                            Sure thing!

                            This is my changeValue() method:

                            @
                            void Clock_Application::changeTime()
                            {
                            std::vector<int> times;
                            QRegExp findTimeSequences("(\d+)");
                            QString currentTime(ui->Output->text());

                            int posOffset(0);
                            while ((posOffset = findTimeSequences.indexIn(currentTime, posOffset)) != -1)
                            {
                                times.push_back(findTimeSequences.cap(1).toInt());
                                posOffset += findTimeSequences.matchedLength();
                            }
                            
                            times[2] += 1;
                            
                            QString outputTime;
                            for (int i = (int) times.size() - 1; i >= 0; i--)
                            {
                                if (times[i] == 60 && i > 0)
                                {
                                    times[i-1] += 1;
                                    times[i] = 0;
                                }
                            
                                QString currentNum; currentNum.setNum(times[i]);
                                if (times[i] <= 9 && i >= 0)
                                {
                                    currentNum.insert(0, QString("0"));
                                }
                                if (i < 2)
                                {
                                    currentNum.append(":");
                                }
                            
                                outputTime.insert(0, currentNum);
                            }
                            
                            ui->Output->setText(outputTime);
                            

                            }
                            @

                            This is my constructor (nothing changed to what I am aware of from the original):

                            @
                            Clock_Application::Clock_Application(QWidget *parent) :
                            QMainWindow(parent),
                            ui(new Ui::Clock_Application)
                            {
                            ui->setupUi(this);
                            }
                            @

                            Thanks for all the help so far, by the way!

                            1 Reply Last reply
                            0
                            • M Offline
                              M Offline
                              MuldeR
                              wrote on last edited by
                              #14

                              [quote author="Flurite" date="1335222560"]
                              Anyhow, the errors were as mentioned in a previous post this:

                              invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 40
                              forward declaration of ‘struct Ui::Clock_Application’ --- at line 11
                              invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 73
                              forward declaration of ‘struct Ui::Clock_Application’ --- at line 11,

                              Lines 40 and 73 are lines in my changeValue() method that try and access the widget.. not surprising lol..[/quote]

                              There are different methods to use the .ui files generated with Qt Designer:
                              http://doc-snapshot.qt-project.org/4.8/designer-using-a-ui-file.html

                              It seems that you have decided for the "Using a Pointer Member Variable" method:
                              http://doc-snapshot.qt-project.org/4.8/designer-using-a-ui-file.html#using-a-pointer-member-variable

                              However it seems like you are missing to include the header file (.h) generated by the UIC.
                              You have the forward declaration (probably in your header file), but are missing the actual definition!
                              Make sure you include the header file generated by UIC in your source file...

                              My OpenSource software at: http://muldersoft.com/

                              Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                              Go visit the coop: http://youtu.be/Jay...

                              1 Reply Last reply
                              0
                              • F Offline
                                F Offline
                                Flurite
                                wrote on last edited by
                                #15

                                [quote author="MuldeR" date="1335223272"]
                                [quote author="Flurite" date="1335222560"]
                                Anyhow, the errors were as mentioned in a previous post this:

                                invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 40
                                forward declaration of ‘struct Ui::Clock_Application’ --- at line 11
                                invalid use of incomplete struct type ‘struct Ui::Clock_Application’ --- at line 73
                                forward declaration of ‘struct Ui::Clock_Application’ --- at line 11,

                                Lines 40 and 73 are lines in my changeValue() method that try and access the widget.. not surprising lol..[/quote]

                                There are different methods to use the .ui files generated with Qt Designer:
                                http://doc-snapshot.qt-project.org/4.8/designer-using-a-ui-file.html

                                It seems that you have decided for the "Using a Pointer Member Variable" method:
                                http://doc-snapshot.qt-project.org/4.8/designer-using-a-ui-file.html#using-a-pointer-member-variable

                                However it seems like you are missing to include the header file (.h) generated by the UIC.
                                You have the forward declaration (probably in your header file), but are missing the actual definition!
                                Make sure you include the header file generated by UIC in your source file...[/quote]

                                No wait, you're saying that I did not include the header file in my clock_application.cpp file? I think I did include that. These are the files I have included in my clock_application.cpp file:

                                #include "clock_application.h"
                                #include "ui_clock_application.h"
                                #include "QString"
                                #include "QRegExp"
                                #include "vector"
                                #include "QThread"

                                1 Reply Last reply
                                0
                                • M Offline
                                  M Offline
                                  MuldeR
                                  wrote on last edited by
                                  #16

                                  “ui_clock_application.h” is what the UIC created from your .UI file, right?

                                  Did you inspect that file? In you case it should contain:

                                  @/********************************************************************************
                                  ** Form generated from reading UI file 'Clock_Application.ui'
                                  **
                                  ** Created: Sun 22. Apr 02:04:07 2012
                                  ** by: Qt User Interface Compiler version 4.8.1
                                  **
                                  ** WARNING! All changes made in this file will be lost when recompiling UI file!
                                  ********************************************************************************/

                                  ...

                                  QT_BEGIN_NAMESPACE

                                  class Ui_Clock_Application
                                  {
                                  public:

                                  ....
                                  

                                  }

                                  namespace Ui {
                                  class Clock_Application: public Ui_Clock_Application {};
                                  }@

                                  If that header file does not define Ui::Clock_Application, then that explains why you get the error.

                                  My OpenSource software at: http://muldersoft.com/

                                  Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                                  Go visit the coop: http://youtu.be/Jay...

                                  1 Reply Last reply
                                  0
                                  • F Offline
                                    F Offline
                                    Flurite
                                    wrote on last edited by
                                    #17

                                    I do not know. It's included in the .cpp file, but I cannot find it in the project's folder.

                                    1 Reply Last reply
                                    0
                                    • M Offline
                                      M Offline
                                      MuldeR
                                      wrote on last edited by
                                      #18

                                      Actually your compiler would throw an error, if you include a file that does not exist.

                                      So it has to exist - somewhere.

                                      If you create GUI's with the Qt Designer, you first get a .UI file. But C++ doesn't know anything about .UI files.

                                      The UIC program needs to be used to create a C++ header file (.h) from your UI file.

                                      Then the header file created by UIC can be included. It contains the required definitions, of Ui::MyDialgClass.

                                      In your case, it should contain the definition of Ui::Clock_Application. Otherwise you have a problem...

                                      My OpenSource software at: http://muldersoft.com/

                                      Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                                      Go visit the coop: http://youtu.be/Jay...

                                      1 Reply Last reply
                                      0
                                      • F Offline
                                        F Offline
                                        Flurite
                                        wrote on last edited by
                                        #19

                                        Hmm.. I'm positive that I used Qt Designer.. but I'm somehow doubting that's the problem because my program will run if I reset it to what it originally was.

                                        clock_application.h contains my definition of Clock_Application

                                        1 Reply Last reply
                                        0
                                        • M Offline
                                          M Offline
                                          MuldeR
                                          wrote on last edited by
                                          #20

                                          Defining your own class is not sufficient.

                                          Somehow the code generated by UIC (based on your .UI file from the Qt Designer) needs to be incorporated.

                                          And Qt offers different ways to do that. You apparently chose the "Using a Pointer Member Variable" way.

                                          Please carefully read:
                                          http://doc-snapshot.qt-project.org/4.8/designer-using-a-ui-file.html

                                          My OpenSource software at: http://muldersoft.com/

                                          Qt v4.8.6 MSVC 2013, static/shared: http://goo.gl/BXqhrS

                                          Go visit the coop: http://youtu.be/Jay...

                                          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