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. My first attempt to create a calculator as a novice in Qt programming
Forum Updated to NodeBB v4.3 + New Features

My first attempt to create a calculator as a novice in Qt programming

Scheduled Pinned Locked Moved Unsolved General and Desktop
29 Posts 6 Posters 8.4k Views 5 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.
  • T Offline
    T Offline
    tomy
    wrote on 6 Jan 2017, 14:33 last edited by tomy 1 Jun 2017, 14:36
    #1

    Hello guys,

    Using very fundamental concepts I got from the book I read about Qt, I encouraged myself to create an app, My_First_Calculator!

    I don't want to make it a complete real app at the moment, but rather, I want to develop it gradually. That is, when one of my questions here will be answered, then I consider the second aspect of changes step-by-step, and ask questions I will have in mind here, to make it appear like a real app finally.

    These are its files. Please look at them and I have a question on it:

    As you see, there are many repetitive lines of code, for example for the connects, and the private slots. Their lines all do logically only two simple tasks. Couldn't we use one slot for those ten slots (0 through 9) and one connect for those ten connects (zero through nine)?

    Please don't forget I'm new in Qt and if you suggest advanced topics I may not be able to understand. So please give me the most basic and simple solutions for my question.
    Thanks so much in advance.

    Here is the files. First, My_First_Calculator.h:

    #ifndef MY_FIRST_CALCULATOR_H
    #define MY_FIRST_CALCULATOR_H
    #include <QDialog>
    
    class QPushButton;
    class QLineEdit;
    
    class My_First_Calculator : public QDialog
    {
        Q_OBJECT
    public:
        My_First_Calculator(QWidget* parent = 0);
    
    private slots:
        void show_number_zero();
        void show_number_one();
        void show_number_two();
        void show_number_three();
        void show_number_four();
        void show_number_five();
        void show_number_six();
        void show_number_seven();
        void show_number_eight();
        void show_number_nine();
    
    private:
        QLineEdit* lineEdit;
    
        QPushButton* zero;
        QPushButton* one;
        QPushButton* two;
        QPushButton* three;
        QPushButton* four;
        QPushButton* five;
        QPushButton* six;
        QPushButton* seven;
        QPushButton* eight;
        QPushButton* nine;
    
        QPushButton* quit;
    };
    
    #endif // MY_FIRST_CALCULATOR_H
    
    

    And this is My_First_Calculator.cpp:

    #include <QtWidgets>
    #include <QDebug>
    #include "my_first_calculator.h"
    
    My_First_Calculator::My_First_Calculator(QWidget* parent)
             :QDialog(parent)
    {
         lineEdit = new QLineEdit;
    
         zero = new QPushButton(tr("0"));
         one = new QPushButton(tr("1"));
         two = new QPushButton(tr("2"));
         three = new QPushButton(tr("3"));
         four = new QPushButton(tr("4"));
         five = new QPushButton(tr("5"));
         six = new QPushButton(tr("6"));
         seven = new QPushButton(tr("7"));
         eight = new QPushButton(tr("8"));
         nine = new QPushButton(tr("9"));
    
         quit = new QPushButton(tr("Close"));
    
         connect(zero, SIGNAL(clicked(bool)), this, SLOT(show_number_zero()));
         connect(one, SIGNAL(clicked(bool)), this, SLOT(show_number_one()));
         connect(two, SIGNAL(clicked(bool)), this, SLOT(show_number_two()));
         connect(three, SIGNAL(clicked(bool)), this, SLOT(show_number_three()));
         connect(four, SIGNAL(clicked(bool)), this, SLOT(show_number_four()));
         connect(five, SIGNAL(clicked(bool)), this, SLOT(show_number_five()));
         connect(six, SIGNAL(clicked(bool)), this, SLOT(show_number_six()));
         connect(seven, SIGNAL(clicked(bool)), this, SLOT(show_number_seven()));
         connect(eight, SIGNAL(clicked(bool)), this, SLOT(show_number_eight()));
         connect(nine, SIGNAL(clicked(bool)), this, SLOT(show_number_nine()));
    
         connect(quit, SIGNAL(clicked(bool)), this, SLOT(close()));
    
         QHBoxLayout* Hlayout1 = new QHBoxLayout;
         Hlayout1 -> addWidget(lineEdit);
    
         QHBoxLayout* Hlayout2 = new QHBoxLayout;
         Hlayout2 -> addWidget(one);
         Hlayout2 -> addWidget(two);
         Hlayout2 -> addWidget(three);
    
         QHBoxLayout* Hlayout3 = new QHBoxLayout;
         Hlayout3 -> addWidget(four);
         Hlayout3 -> addWidget(five);
         Hlayout3 -> addWidget(six);
    
         QHBoxLayout* Hlayout4 = new QHBoxLayout;
         Hlayout4 -> addWidget(seven);
         Hlayout4 -> addWidget(eight);
         Hlayout4 -> addWidget(nine);
    
         QHBoxLayout* Hlayout5 = new QHBoxLayout;
         Hlayout5 -> addWidget(zero);
         Hlayout5 -> addWidget(quit);
    
         QVBoxLayout* vlayout = new QVBoxLayout;
         vlayout -> addLayout(Hlayout1);
         vlayout -> addLayout(Hlayout2);
         vlayout -> addLayout(Hlayout3);
         vlayout -> addLayout(Hlayout4);
         vlayout -> addLayout(Hlayout5);
    
         setLayout(vlayout);
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_zero()
    {
        lineEdit -> setText(QString::number(0));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_one()
    {
        lineEdit -> setText(QString::number(1));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_two()
    {
        lineEdit -> setText(QString::number(2));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_three()
    {
        lineEdit -> setText(QString::number(3));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_four()
    {
        lineEdit -> setText(QString::number(4));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_five()
    {
        lineEdit -> setText(QString::number(5));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_six()
    {
        lineEdit -> setText(QString::number(6));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_seven()
    {
        lineEdit -> setText(QString::number(7));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_eight()
    {
        lineEdit -> setText(QString::number(8));
    }
    
    //***************************************
    
    void My_First_Calculator::show_number_nine()
    {
        lineEdit -> setText(QString::number(9));
    }
    
    

    And this is main.cpp:

    #include <QApplication>
    #include "my_first_calculator.h"
    
    int main(int argc , char* argv[])
    {
        QApplication app(argc, argv);
        My_First_Calculator* myCal = new My_First_Calculator;
        myCal -> show();
        return app.exec();
    }
    
    
    1 Reply Last reply
    1
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on 6 Jan 2017, 14:39 last edited by mrjj 1 Jun 2017, 14:43
      #2

      Hi
      It does sound like a good plan. :)

      There is nothing wrong with letting widgets send signals to same SLOT.
      you can know which button/widget that send the signal using sender().

      However there is also
      http://doc.qt.io/qt-5/qsignalmapper.html#details
      To help such design.

      Update:
      the shared slot would be like

      void MainWindow::on_pushButton_2_released() { 
          QPushButton* TheButt = qobject_cast<QPushButton*>( sender());
          if ( TheButt ) {                
          }
      }
      
      1 Reply Last reply
      2
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 6 Jan 2017, 14:47 last edited by Chris Kawa 1 Jun 2017, 14:49
        #3

        Couldn't we use one slot for those ten slots (0 through 9) and one connect for those ten connects (zero through nine)?

        Sure you could. You could make all of this repetitive code go away.

        For starters: instead of a separately named variable for each button you could have a single vector of them:

        QVector<QPushButton*> buttons;
        

        then instead of 10 initializations you would do a for loop:

        for (int i=0; i < 10; ++i)
           buttons.push_back(new QPushButton(QString::number(i)));
        

        Then you would create one single slot with parameter instead of one for each button:

        private slots:
           void show_number(int value);
        

        then implement it:

        void My_First_Calculator::show_number(int value)
        {
            lineEdit -> setText(QString::number(value));
        }
        

        and instead of individual connects you can again run a loop:

        for (int i=0; i < buttons.size(); ++i)
            connect(buttons.at(i), &QPushButton::clicked, [=]{ show_number(i); });
        

        You could also use a QGridLayout and another loop instead of the repetitive placement of each widget.

        T 1 Reply Last reply 6 Jan 2017, 15:16
        4
        • Chris KawaC Chris Kawa
          6 Jan 2017, 14:47

          Couldn't we use one slot for those ten slots (0 through 9) and one connect for those ten connects (zero through nine)?

          Sure you could. You could make all of this repetitive code go away.

          For starters: instead of a separately named variable for each button you could have a single vector of them:

          QVector<QPushButton*> buttons;
          

          then instead of 10 initializations you would do a for loop:

          for (int i=0; i < 10; ++i)
             buttons.push_back(new QPushButton(QString::number(i)));
          

          Then you would create one single slot with parameter instead of one for each button:

          private slots:
             void show_number(int value);
          

          then implement it:

          void My_First_Calculator::show_number(int value)
          {
              lineEdit -> setText(QString::number(value));
          }
          

          and instead of individual connects you can again run a loop:

          for (int i=0; i < buttons.size(); ++i)
              connect(buttons.at(i), &QPushButton::clicked, [=]{ show_number(i); });
          

          You could also use a QGridLayout and another loop instead of the repetitive placement of each widget.

          T Offline
          T Offline
          tomy
          wrote on 6 Jan 2017, 15:16 last edited by
          #4

          @Chris-Kawa:
          Thank you very much. :) It was exactly what I was looking for. THANKS.

          I used your instructions but one question here about the connect.
          Can't we use it this way rather than yours:

          connect(buttons[i], SIGNAL(clicked(bool)), this, SLOT(show_number(i)));
          or
          connect(buttons.at(i), SIGNAL(clicked(bool)), this, SLOT(show_number(i)));
          ?

          Your connect version is vague for me because of my being that novice. :)

          And is there a good example of using QGridLayout for my case please?

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on 6 Jan 2017, 15:29 last edited by Chris Kawa 1 Jun 2017, 16:39
            #5

            No, you can't use it like that. The macro takes types of parameters (int, string etc.), not values ( 42, "foo" etc.) so passing i there won't work.

            The SIGNAL/SLOT macro is the old connect syntax. There's a new, better syntax using function pointers.
            Instead of the old connect(sender, SIGNAL(signal(type,type)), receiver, SLOT(slot(type,type)));
            you can write the new connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot);.
            It's better because it is checked at compile time, type safe and is generally faster.

            There's also a version that takes any function instead of receiver and slot: connect(sender, &SenderClass::signal, function).
            I used that last syntax, except I used a c++11 lambda as a function. You can read my other post for an introduction to lambdas if you're not familiar with them.

            As for the grid layout, it would be something like this:

            QGridLayout* layout = new QGridLayout();
            
            //lets say you want a 3 column layout:
            for (int i = 0; i < buttons.size(); ++i)
            {
               int row = i / 3;
               int column = i % 3;
               layout->addWidget(buttons.at(i), row, column);
            }
            
            1 Reply Last reply
            4
            • T Offline
              T Offline
              tomy
              wrote on 6 Jan 2017, 16:24 last edited by tomy 1 Jun 2017, 16:27
              #6

              Thank you again.

              Instead of the old connect(sender, SIGNAL(signal(type,type)), receiver, SLOT(slot(type,type)));

              I'm studying an old book (Qt 4.x) and although want to learn new changes in newer versions of Qt, I would like to learn them after finishing the book so that I don't be confused with the differences of the book and new resources.
              So how should I use the connect macro in old style for the purpose of my code, here, please?

              And thanks also for the GridLayout example.

              PS: I used QGridLayout* layout.

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on 6 Jan 2017, 16:39 last edited by Chris Kawa 1 Jun 2017, 16:41
                #7

                Right, I'm not sure it's a good idea to learn the obsolete stuff first, but anyway...

                With the old syntax you can use a QSignalMapper, like @mrjj suggested.
                You would create an instance of it as a member variable:

                private:
                    QSignalMapper buttonMapper;
                

                Then you would add mappings for the buttons (you can use the same loop as for creating them):

                for (int i=0; i < 10; ++i) {
                   //create the button same as previously
                   QPushButton* button = new QPushButton(QString::number(i));
                   buttons.push_back(button);
                
                   //create the mapping. When button emits "clicked" the mapper will emit "mapped(int)" signal with the value i we mapped for this button
                   buttonMapper.setMapping(button, i);
                   connect(button, SIGNAL(clicked(bool)), &buttonMapper, SLOT(map()));
                }
                

                Now all is left is to connect the mapper to the original slot:

                connect(&buttonMapper, SIGNAL(mapped(int)), this, SLOT(show_number(int)));
                

                PS. I write this stuff out of my head. Sorry for the little errors (the missing * in previous post, I fixed it).

                1 Reply Last reply
                2
                • T Offline
                  T Offline
                  tomy
                  wrote on 6 Jan 2017, 20:48 last edited by tomy 1 Jun 2017, 20:50
                  #8

                  Thank you. Using the link dear mrjj had suggested, I changed the code this waw.
                  My_First_Calculator.h:

                  /#ifndef MY_FIRST_CALCULATOR_H
                  #define MY_FIRST_CALCULATOR_H
                  #include <QDialog>
                  #include <QSignalMapper>
                  #include <QStringList>
                  
                  class QPushButton;
                  class QLineEdit;
                  
                  class My_First_Calculator : public QDialog
                  {
                      Q_OBJECT
                  public:
                      My_First_Calculator(const QStringList& texts
                                          ,QWidget* parent = 0);
                  
                  signals:
                     void clicked(const QString& text);
                  
                  private:
                      QLineEdit* lineEdit;
                      QSignalMapper* signalMapper;
                      QPushButton* quit;
                  };
                  
                  #endif // MY_FIRST_CALCULATOR_H
                  
                  

                  My_First_Calculator.cpp:

                  #include <QtWidgets>
                  #include "my_first_calculator.h"
                  
                  My_First_Calculator::My_First_Calculator(const QStringList& texts,
                            QWidget* parent = 0) : QDialog(parent)
                  {
                       lineEdit = new QLineEdit;
                       quit = new QPushButton(tr("Close"));
                  
                       signalMapper = new QSignalMapper(this);
                       QGridLayout* gridLayout = new QGridLayout;
                  
                       for(int i=0; i<texts.size(); ++i)
                       {
                           QPushButton* button = new QPushButton(texts[i]);
                           connect(button, SIGNAL(clicked(bool)),
                                   signalMapper, SLOT(map()));
                           signalMapper -> setMapping(button, texts[i]);
                           gridLayout -> addWidget(button, i/3, i%3);
                       }
                  
                       connect(signalMapper, SIGNAL(mapped(QString)), this,
                               SIGNAL(clicked(QString)));
                  
                  
                  
                       connect(quit, SIGNAL(clicked(bool)), this, SLOT(close()));
                  
                       QVBoxLayout* layout = new QVBoxLayout;
                       layout -> addWidget(lineEdit);
                       layout -> addLayout(gridLayout);
                       layout -> addWidget(quit);
                       setLayout(layout);
                  }
                  
                  

                  And main.cpp:

                  #include <QApplication>
                  #include "my_first_calculator.h"
                  
                  int main(int argc , char* argv[])
                  {
                      QApplication app(argc, argv);
                      QStringList texts;
                      texts << "0" << "1" << "2" << "3" << "4"
                            << "5" << "6" << "7" << "8" << "9";
                      My_First_Calculator myCal(texts);
                      myCal.show();
                      return app.exec();
                  }
                  
                  

                  I get the following error. I guess I need to supply an argument for the parent parameter of QDialog when creating myCal instance in main.cpp.

                  some questions:

                  1- But do I need to inherit from QDialog in the.h file?
                  2- Is it a good choice or should I inherit from QWidget?
                  3- Is the following error related to my guess please?
                  4- Have I changed my code correctly, according to the example mrjj suggested?

                  C:\Users\ME\Documents\Qt\My_First_Calculator\my_first_calculator.cpp:5: error: default argument given for parameter 2 of 'My_First_Calculator::My_First_Calculator(const QStringList&, QWidget)' [-fpermissive]
                  QWidget* parent = 0) : QDialog(parent)*
                  ^

                  1 Reply Last reply
                  1
                  • Chris KawaC Offline
                    Chris KawaC Offline
                    Chris Kawa
                    Lifetime Qt Champion
                    wrote on 6 Jan 2017, 21:03 last edited by Chris Kawa 1 Jun 2017, 21:03
                    #9
                    1. QDialog is a specialized case of QWidget. You don't have to subclass it if you don't use its features (which you don't seem to). In this case QWidget would be enough (but change it in both .h and .cpp if you do).
                    2. You don't use any of special QDialog features so it doesn't matter.
                    3. No, It means you provided a default argument in the constructor implementation in the .cpp file. Default arguments go only in the header:
                    //the header:
                    My_First_Calculator(const QStringList& texts ,QWidget* parent = 0);
                    
                    //the implementation:
                    My_First_Calculator::My_First_Calculator(const QStringList& texts, QWidget* parent) : QDialog(parent) //no = 0 here
                    
                    1. The signal mapper looks to be hooked up correctly, but you don't connect anything to the clicked() signal of your class so nothing will actually happen.
                    T 1 Reply Last reply 6 Jan 2017, 21:11
                    2
                    • Chris KawaC Chris Kawa
                      6 Jan 2017, 21:03
                      1. QDialog is a specialized case of QWidget. You don't have to subclass it if you don't use its features (which you don't seem to). In this case QWidget would be enough (but change it in both .h and .cpp if you do).
                      2. You don't use any of special QDialog features so it doesn't matter.
                      3. No, It means you provided a default argument in the constructor implementation in the .cpp file. Default arguments go only in the header:
                      //the header:
                      My_First_Calculator(const QStringList& texts ,QWidget* parent = 0);
                      
                      //the implementation:
                      My_First_Calculator::My_First_Calculator(const QStringList& texts, QWidget* parent) : QDialog(parent) //no = 0 here
                      
                      1. The signal mapper looks to be hooked up correctly, but you don't connect anything to the clicked() signal of your class so nothing will actually happen.
                      T Offline
                      T Offline
                      tomy
                      wrote on 6 Jan 2017, 21:11 last edited by tomy 1 Jun 2017, 21:11
                      #10

                      @Chris-Kawa

                      you don't connect anything to the clicked() signal of your class so nothing will actually happen.

                      Yes, you are right. Nothing happens.
                      But I've used the following connect in My_First_Calculator.cpp. Don't you mean this?

                      connect(signalMapper, SIGNAL(mapped(QString)), this,
                                 SIGNAL(clicked(QString)));
                      
                      1 Reply Last reply
                      0
                      • Chris KawaC Offline
                        Chris KawaC Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on 6 Jan 2017, 21:24 last edited by
                        #11

                        Yes, when signal mapper emits mapped your widget emits clicked and that's it. No one is connected to that signal so nothing happens.
                        I think what you meant to do is to hook the signal mapper to a show_number slot:

                        //header
                        private slots:
                            void show_number(const QSring& text);
                        
                        //cpp
                        void My_First_Calculator::show_number(const QSring& text)
                        {
                            lineEdit -> setText(text);
                        }
                        

                        and connect it like this:

                        connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(show_number(QString)));
                        
                        T 1 Reply Last reply 6 Jan 2017, 21:36
                        2
                        • Chris KawaC Chris Kawa
                          6 Jan 2017, 21:24

                          Yes, when signal mapper emits mapped your widget emits clicked and that's it. No one is connected to that signal so nothing happens.
                          I think what you meant to do is to hook the signal mapper to a show_number slot:

                          //header
                          private slots:
                              void show_number(const QSring& text);
                          
                          //cpp
                          void My_First_Calculator::show_number(const QSring& text)
                          {
                              lineEdit -> setText(text);
                          }
                          

                          and connect it like this:

                          connect(signalMapper, SIGNAL(mapped(QString)), this, SLOT(show_number(QString)));
                          
                          T Offline
                          T Offline
                          tomy
                          wrote on 6 Jan 2017, 21:36 last edited by
                          #12

                          @Chris-Kawa
                          Thank you. It works as is expected now.

                          I also removed

                          signals:
                            void clicked(const QString& text);
                          

                          in .h file because I though it was useless.

                          Another question. (Please excuse me for asking those many questions)
                          Do I need to essentially inherit from QDialog, that is, can't I remove it this way:

                          class My_First_Calculator  {
                              Q_OBJECT
                          

                          ?

                          1 Reply Last reply
                          0
                          • Chris KawaC Offline
                            Chris KawaC Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on 6 Jan 2017, 21:42 last edited by
                            #13

                            can't I remove it this way

                            No, you can't. You need a window that you can show, You need to be able to put widgets in it, you need a layout etc. All those things are functions of a QWidget (QDialog is a subclass of QWidget).
                            Look in the main() function. There's myCal.show();. show() is a method of a QWidget. Look in the constructor. There's setLayout(layout);. setLayout() is a method of QWidget. There's also connect(.... connect() is also a method of QWidget. There are more examples but the answer is no, you need to at least inherit from QWidget.

                            1 Reply Last reply
                            2
                            • T Offline
                              T Offline
                              tomy
                              wrote on 6 Jan 2017, 21:46 last edited by
                              #14

                              Thank you very much.
                              The first step is finished. I will think about the code well to understand every part properly. And think to start a new means to develop it. If I have question I will post them again.
                              Bye for now.

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                tomy
                                wrote on 14 Jan 2017, 15:00 last edited by
                                #15

                                Hello guys, I'm back to this thread. :)

                                I had a very little time for Qt (I'm involving many aspects of CS and scheduled my works :)) using which I went a few steps on the process of developing my fist app the way I mentioned in the first post of this thread.

                                Anyway, Thanks for your patient and we will go to the game!

                                The changes I make (just using the experience I have on C++) are as follows:

                                My_First_Calculator.h

                                #ifndef MY_FIRST_CALCULATOR_H
                                #define MY_FIRST_CALCULATOR_H
                                #include <QDialog>
                                #include <QSignalMapper>
                                #include <QStringList>
                                
                                class QLineEdit;
                                
                                class My_First_Calculator : public QDialog
                                {
                                    Q_OBJECT
                                public:
                                    My_First_Calculator(const QStringList& texts
                                                        ,QWidget* parent = 0);
                                
                                private slots:
                                    void show_number(const QString&);
                                    void reset();
                                
                                private:
                                    QLineEdit* lineEdit;
                                    QSignalMapper* signalMapper;
                                    QString temp_text;
                                };
                                
                                #endif // MY_FIRST_CALCULATOR_H
                                

                                My_First_Calculator.cpp:

                                #include <QtWidgets>
                                #include "my_first_calculator.h"
                                
                                My_First_Calculator::My_First_Calculator(const QStringList& texts,
                                          QWidget* parent) : QDialog(parent)
                                {
                                     lineEdit = new QLineEdit;
                                     QPushButton* quit = new QPushButton(tr("Close"));
                                     QPushButton* clear = new QPushButton(tr("C"));
                                
                                     signalMapper = new QSignalMapper(this);
                                     QGridLayout* gridLayout = new QGridLayout;
                                
                                     for(int i=0; i<texts.size(); ++i)
                                      {
                                         QPushButton* button = new QPushButton(texts[i]);
                                
                                         connect(button, SIGNAL(clicked(bool)),
                                                 signalMapper, SLOT(map()));
                                
                                         signalMapper -> setMapping(button, texts[i]);
                                         gridLayout -> addWidget(button, i/3, i%3);
                                      }
                                
                                     connect(signalMapper, SIGNAL(mapped(QString)), this,
                                             SLOT(show_number(QString)));
                                
                                     connect(quit, SIGNAL(clicked(bool)), this, SLOT(close()));
                                     connect(clear, SIGNAL(clicked(bool)), this, SLOT(reset()));
                                
                                     QVBoxLayout* layout = new QVBoxLayout;
                                     layout -> addWidget(lineEdit);
                                     layout -> addLayout(gridLayout);
                                     layout -> addWidget(quit);
                                     layout -> addWidget(clear);
                                     setLayout(layout);
                                }
                                
                                //****************************
                                
                                void My_First_Calculator::show_number(const QString& text)
                                {
                                    if(text == "C")
                                        temp_text.clear();
                                    else  temp_text.append(text);
                                    lineEdit -> setText(temp_text);
                                }
                                
                                //*****************************************
                                
                                void My_First_Calculator::reset()
                                {
                                    emit show_number("C");
                                }
                                

                                main.cpp:

                                #include <QApplication>
                                #include "my_first_calculator.h"
                                
                                int main(int argc , char* argv[])
                                {
                                    QApplication app(argc, argv);
                                
                                    QStringList texts;
                                    texts << "0" << "1" << "2" << "3" << "4"
                                          << "5" << "6" << "7" << "8" << "9";
                                
                                    My_First_Calculator myCal(texts);
                                    myCal.show();
                                
                                    return app.exec();
                                }
                                

                                At any given time, I try to add some more features to the app. but now two questions:)

                                1- Is there any weak part in the code that should be replaced?
                                2- Apparently since I didn't use the Designer for it, I can't change the form my mouse! Is it true? If so, what nifty means is there to change the shape of the form? I mean buttons, sizes, or whatsoever?

                                ThankX!

                                1 Reply Last reply
                                0
                                • mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on 14 Jan 2017, 15:27 last edited by mrjj
                                  #16

                                  Hi
                                  All is debatable but my points would be :
                                  You are using good variable names but Im not crazy with underscores.
                                  Seen code where used a lot and it very hard to read.
                                  Not issue here but now its mentioned.
                                  Also , choose a style for variable naming and use it all over.
                                  QLineEdit* lineEdit; <<< qt style
                                  QSignalMapper* signalMapper; << qt style
                                  QString temp_text; << other style

                                  Also
                                  void My_First_Calculator::reset()
                                  why send a "c" to show_number to reset?
                                  Why not directly

                                  void My_First_Calculator::reset()
                                  {
                                  temp_text.clear();
                                  lineEdit -> setText("");
                                  }

                                  • 2- Apparently since I didn't use the Designer
                                    Well if you do not use UI files, then you just adjust from code.
                                    with resize or setGeometry.
                                    However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
                                    http://doc.qt.io/qt-5/layout.html
                                  T 1 Reply Last reply 16 Jan 2017, 12:08
                                  2
                                  • mrjjM mrjj
                                    14 Jan 2017, 15:27

                                    Hi
                                    All is debatable but my points would be :
                                    You are using good variable names but Im not crazy with underscores.
                                    Seen code where used a lot and it very hard to read.
                                    Not issue here but now its mentioned.
                                    Also , choose a style for variable naming and use it all over.
                                    QLineEdit* lineEdit; <<< qt style
                                    QSignalMapper* signalMapper; << qt style
                                    QString temp_text; << other style

                                    Also
                                    void My_First_Calculator::reset()
                                    why send a "c" to show_number to reset?
                                    Why not directly

                                    void My_First_Calculator::reset()
                                    {
                                    temp_text.clear();
                                    lineEdit -> setText("");
                                    }

                                    • 2- Apparently since I didn't use the Designer
                                      Well if you do not use UI files, then you just adjust from code.
                                      with resize or setGeometry.
                                      However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
                                      http://doc.qt.io/qt-5/layout.html
                                    T Offline
                                    T Offline
                                    tomy
                                    wrote on 16 Jan 2017, 12:08 last edited by
                                    #17

                                    @mrjj said in My first attempt to create a calculator as a novice in Qt programming:

                                    Hi
                                    All is debatable but my points would be :
                                    You are using good variable names but Im not crazy with underscores.
                                    Seen code where used a lot and it very hard to read.

                                    Hi. :)

                                    You are right. It's hard for reading. I will put enough white spaces and comments when it is finished. :)
                                    And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                    Not issue here but now its mentioned.
                                    Also , choose a style for variable naming and use it all over.
                                    QLineEdit* lineEdit; <<< qt style
                                    QSignalMapper* signalMapper; << qt style
                                    QString temp_text; << other style

                                    How to choose a style please?

                                    Also
                                    void My_First_Calculator::reset()
                                    why send a "c" to show_number to reset?
                                    Why not directly

                                    void My_First_Calculator::reset()
                                    {
                                    temp_text.clear();
                                    lineEdit -> setText("");
                                    }

                                    Yeah, very handy, thanks. I applied it. :)

                                    • 2- Apparently since I didn't use the Designer
                                      Well if you do not use UI files, then you just adjust from code.
                                      with resize or setGeometry.
                                      However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
                                      http://doc.qt.io/qt-5/layout.html

                                    Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?

                                    mrjjM 1 Reply Last reply 16 Jan 2017, 12:32
                                    0
                                    • T tomy
                                      16 Jan 2017, 12:08

                                      @mrjj said in My first attempt to create a calculator as a novice in Qt programming:

                                      Hi
                                      All is debatable but my points would be :
                                      You are using good variable names but Im not crazy with underscores.
                                      Seen code where used a lot and it very hard to read.

                                      Hi. :)

                                      You are right. It's hard for reading. I will put enough white spaces and comments when it is finished. :)
                                      And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                      Not issue here but now its mentioned.
                                      Also , choose a style for variable naming and use it all over.
                                      QLineEdit* lineEdit; <<< qt style
                                      QSignalMapper* signalMapper; << qt style
                                      QString temp_text; << other style

                                      How to choose a style please?

                                      Also
                                      void My_First_Calculator::reset()
                                      why send a "c" to show_number to reset?
                                      Why not directly

                                      void My_First_Calculator::reset()
                                      {
                                      temp_text.clear();
                                      lineEdit -> setText("");
                                      }

                                      Yeah, very handy, thanks. I applied it. :)

                                      • 2- Apparently since I didn't use the Designer
                                        Well if you do not use UI files, then you just adjust from code.
                                        with resize or setGeometry.
                                        However, for app like yours, one would use layout to make it auto scale the buttons to any size if dialog is resized.
                                        http://doc.qt.io/qt-5/layout.html

                                      Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on 16 Jan 2017, 12:32 last edited by mrjj
                                      #18

                                      Hi :)

                                      And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                      Means, I don't like so much. ( reading it )

                                      How to choose a style please?

                                      Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
                                      working solo then just choose one and stick to it.
                                      Its mostly about if you write it like
                                      SomeName
                                      someName
                                      somename
                                      some_name

                                      so the important part is just to name it the same way each time and not mixing it.

                                      • Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
                                        Those are fine and should make it scale all when you resize the window.
                                      T 1 Reply Last reply 16 Jan 2017, 12:45
                                      1
                                      • mrjjM mrjj
                                        16 Jan 2017, 12:32

                                        Hi :)

                                        And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                        Means, I don't like so much. ( reading it )

                                        How to choose a style please?

                                        Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
                                        working solo then just choose one and stick to it.
                                        Its mostly about if you write it like
                                        SomeName
                                        someName
                                        somename
                                        some_name

                                        so the important part is just to name it the same way each time and not mixing it.

                                        • Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
                                          Those are fine and should make it scale all when you resize the window.
                                        T Offline
                                        T Offline
                                        tomy
                                        wrote on 16 Jan 2017, 12:45 last edited by tomy
                                        #19

                                        @mrjj said in My first attempt to create a calculator as a novice in Qt programming:

                                        Hi :)

                                        And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                        Means, I don't like so much. ( reading it )

                                        How to choose a style please?

                                        Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
                                        working solo then just choose one and stick to it.
                                        Its mostly about if you write it like
                                        SomeName
                                        someName
                                        somename
                                        some_name

                                        so the important part is just to name it the same way each time and not mixing it.

                                        • Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
                                          Those are fine and should make it scale all when you resize the window.

                                        Thank you :)

                                        I put some other widgets as well, like another lineEdit for the results and so on.
                                        Now I come across two other questions. :)

                                        1- Assume I have a button like this:

                                        QPushButton* two = new QPushButton(tr("2"))
                                        

                                        How do I send that string ("2") to the show_number(const QString& text) so that it will be shown by the lineEdit in the form when running the program? I mean without using a signalMapper? Apparently I can't use parameters in connect to send for that function. :(

                                        2- Consider I want to store the contents the lineEdit into a vector of char (so that I will be able to calculate the contents later). How to do it lease?

                                        EDITED!

                                        jsulmJ 1 Reply Last reply 16 Jan 2017, 13:15
                                        0
                                        • T tomy
                                          16 Jan 2017, 12:45

                                          @mrjj said in My first attempt to create a calculator as a novice in Qt programming:

                                          Hi :)

                                          And what do you mean by "not crazy with underscore" please? (not a native speaker. :( )

                                          Means, I don't like so much. ( reading it )

                                          How to choose a style please?

                                          Well, Thats is mostly what you like. Sometimes in teams , we must agree but if you are
                                          working solo then just choose one and stick to it.
                                          Its mostly about if you write it like
                                          SomeName
                                          someName
                                          somename
                                          some_name

                                          so the important part is just to name it the same way each time and not mixing it.

                                          • Apparently, in my form until here, using only HBoxLayout, VBoxLayout, and GridLayout are fine. Do you not agree?
                                            Those are fine and should make it scale all when you resize the window.

                                          Thank you :)

                                          I put some other widgets as well, like another lineEdit for the results and so on.
                                          Now I come across two other questions. :)

                                          1- Assume I have a button like this:

                                          QPushButton* two = new QPushButton(tr("2"))
                                          

                                          How do I send that string ("2") to the show_number(const QString& text) so that it will be shown by the lineEdit in the form when running the program? I mean without using a signalMapper? Apparently I can't use parameters in connect to send for that function. :(

                                          2- Consider I want to store the contents the lineEdit into a vector of char (so that I will be able to calculate the contents later). How to do it lease?

                                          EDITED!

                                          jsulmJ Offline
                                          jsulmJ Offline
                                          jsulm
                                          Lifetime Qt Champion
                                          wrote on 16 Jan 2017, 13:15 last edited by jsulm
                                          #20

                                          @tomy

                                          1. In the slot:
                                          QString s = reinterpret_cast<QPushButton*>(sender())->text();
                                          
                                          1. Why? If user enters number 123, why do you want to store this number in a vector like ['1', '2', '3']? It is actually a vector of strings. For that you can split the string, see http://doc.qt.io/qt-5/qstring.html#split

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

                                          T 1 Reply Last reply 16 Jan 2017, 13:56
                                          1

                                          • Login

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