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. Invalid use of non-static data member "ui"
Forum Updated to NodeBB v4.3 + New Features

Invalid use of non-static data member "ui"

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 3 Posters 9.2k Views 2 Watching
  • 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.
  • HamishH Offline
    HamishH Offline
    Hamish
    wrote on last edited by
    #1

    Sorry if my terms are incorrect i come from a java background.
    Im trying to create a util class to just make my project more organised but I'm having problems accessing my UI from an external class, at first in the header file the UI was private so i changed it to public but now its complaining with the error "Invalid use of non-static data member "ui"" Does anyone know how to fix this? Should I be making UI public or should I use another method? Here is my code, only the relevant parts of the classes

    //QUIZ.CPP
    //Creates "Quiz" widget
    Quiz::Quiz(QWidget *parent) :
        QWidget(parent),
        ui( new Ui::Quiz)
    {
        ui->setupUi(this);
        ui->console->append("Type \"start\" to go");
    }
    
    //Destroys widget on exit
    Quiz::~Quiz()
    {
        delete ui;
    }
    
    //QUIZ.H
    namespace Ui {
    class Quiz;
    }
    
    class Quiz : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Quiz(QWidget *parent = 0);
        ~Quiz();
    private slots:
        void on_button_clicked();
    
        void on_input_returnPressed();
    public:
        Ui::Quiz *ui;
    };
    
    #endif // QUIZ_H
    
    //UTIL.CPP
    void appendConsole(QString string) {
        Quiz::ui->console->append(string);
    }
    
    void appendInput(QString string) {
        Quiz::ui->input->setText(string);
    }
    
    QString getInput() {
        return Quiz::ui->input->text();
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      Welcome to C++ then :)
      It complains because the syntax used
      Quiz::ui->input->setText(string);
      should be
      ui->input->setText(string);

      The syntax
      Quiz::
      is for calling a static method in a class.
      but ui is not static. Its just a private class.
      So compilers whines. :)

      But here comes the bummer. UI is private so you cannot
      say ui->input->setText(string); from external class

      So the options are:
      1: use public function to setData without exposing to exernal class what kind
      of widget that does the real job.
      void appendConsole(QString string) {
      QuizInstance->SetConsoleText(string);
      }
      2:
      Use signals and slot
      http://doc.qt.io/qt-5/signalsandslots.html
      here you would define a new signal and slot say
      SetConsoleText(QString Text);
      and connect signal to slot
      and u can then
      emit SetConsoleText("logtext");

      Since you seem to be using normal non class members functions in UTILS.cpp
      then public function seems to be the way to go.

      Also since this is C++, you can make UI public and directly access it but
      that is considered bad practice as you then expose the widgets to rest of program.

      1 Reply Last reply
      0
      • HamishH Offline
        HamishH Offline
        Hamish
        wrote on last edited by Hamish
        #3

        The reason i had it as Quiz::ui is because its not in the same cpp file its in a seperate file called util.cpp, this is for organisation reasons, if i do not do this it throws the error "Use of undeclared 'ui'" so i assumed i needed to mention the class name similar to java

        mrjjM kshegunovK 2 Replies Last reply
        0
        • HamishH Hamish

          The reason i had it as Quiz::ui is because its not in the same cpp file its in a seperate file called util.cpp, this is for organisation reasons, if i do not do this it throws the error "Use of undeclared 'ui'" so i assumed i needed to mention the class name similar to java

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Hamish
          Hi
          The ClassName::Member syntax is used to call static functions in c++.
          THats is, to call a function without a class instance.

          UI is not static so even if not private it would not work.

          Even if UI was public, you would still need a instance to call it
          Quiz myInstance;
          myInstance.ui->consolexxx

          Hope it make sense :)

          1 Reply Last reply
          0
          • HamishH Offline
            HamishH Offline
            Hamish
            wrote on last edited by Hamish
            #5

            Hmm so the only real way to fix my problem is to add the methods involving the ui back into the Quiz.cpp class. So there is no way to hook the ui object in any way?

            mrjjM 1 Reply Last reply
            0
            • HamishH Hamish

              Hmm so the only real way to fix my problem is to add the methods involving the ui back into the Quiz.cpp class. So there is no way to hook the ui object in any way?

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by mrjj
              #6

              @Hamish

              Hi what you mean hook ?

              As long as you have not created an instance of the class
              the UI elements are not live.

              so UTILS.cpp must have an instance anyway. EVEN is UI was public.

              void appendConsole(QString string) {
              QuizPtr->ui->console->append(string);
              }

              EDIT:
              Oh. u did change ui to public..
              Then u just need an instance to allow this..

              1 Reply Last reply
              0
              • HamishH Offline
                HamishH Offline
                Hamish
                wrote on last edited by
                #7

                hmm now i get this problem:
                QWidget: Must construct a QApplication before a QWidget
                The program has unexpectedly finished.

                although the Application is instantiated in the main class before everything else...

                mrjjM 1 Reply Last reply
                0
                • HamishH Hamish

                  hmm now i get this problem:
                  QWidget: Must construct a QApplication before a QWidget
                  The program has unexpectedly finished.

                  although the Application is instantiated in the main class before everything else...

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Hamish
                  Well, if you make global Widgets variables, this can happen.
                  As globals are created first. Before main is run.

                  HamishH 1 Reply Last reply
                  0
                  • mrjjM mrjj

                    @Hamish
                    Well, if you make global Widgets variables, this can happen.
                    As globals are created first. Before main is run.

                    HamishH Offline
                    HamishH Offline
                    Hamish
                    wrote on last edited by
                    #9

                    @mrjj Can i fix this?

                    mrjjM 1 Reply Last reply
                    0
                    • HamishH Hamish

                      @mrjj Can i fix this?

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by mrjj
                      #10

                      @Hamish
                      Yes, often you can
                      Say you have this global widget
                      Quiz MyQuiz;

                      If you do
                      Quiz *MyQuiz;

                      and then in main
                      MyQuiz=new Quiz;

                      It would not complain as global is just a pointer now.

                      But normally we dont use globals at all. All lives in classes.
                      Like mainwindow.

                      ps. remember to call delete MyQuiz; at program end.

                      1 Reply Last reply
                      0
                      • HamishH Hamish

                        The reason i had it as Quiz::ui is because its not in the same cpp file its in a seperate file called util.cpp, this is for organisation reasons, if i do not do this it throws the error "Use of undeclared 'ui'" so i assumed i needed to mention the class name similar to java

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on last edited by kshegunov
                        #11

                        @Hamish

                        The reason i had it as Quiz::ui is because its not in the same cpp file its in a seperate file called util.cpp, this is for organisation reasons, if i do not do this it throws the error "Use of undeclared 'ui'" so i assumed i needed to mention the class name similar to java

                        I often say "C++ is not Java", but mostly is in different context - memory management. Funnily, here it's even more applicable. In Java you are supposed to put every (public) class in it's own file (if I remember correctly), C++ doesn't care, it also doesn't care how you name your files . You can put the declaration in a header and then put the definitions in any cpp you want (as long as you don't duplicate the class/method names). It also doesn't care how many classes (exported or otherwise) you declare in a header file.

                        Well, if you make global Widgets variables, this can happen. As globals are created first. Before main is run.

                        Can i fix this?

                        You shouldn't create anything that's QObject derived before the QCoreApplication constructor has run. The first QObject you create should be the application object. My advice, forget global variables, especially since you appear to not have much experience with C++. In Java they are mostly okay, but with C++ they are a real pain and lead to all sorts of complications. Do as @mrjj suggested and put your objects as members of classes.

                        PS.

                        void appendInput(QString string) {
                            Quiz::ui->input->setText(string);
                        }
                        

                        These functions are global functions, and not class members, you should convert them to methods instead and in these methods you can operate your ui object.

                        Kind regards.

                        Read and abide by the Qt Code of Conduct

                        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