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. Code review
Forum Updated to NodeBB v4.3 + New Features

Code review

Scheduled Pinned Locked Moved Solved General and Desktop
24 Posts 6 Posters 3.0k 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.
  • Q Offline
    Q Offline
    qcoderpro
    wrote on last edited by
    #1

    Hello,

    Will you take a look at my code here. Is it completely correct to you?

    dialogTest.h:

    #ifndef DIALOGTEST_H
    #define DIALOGTEST_H
    
    #include <QDialog>
    
    class QPushButton;
    class QDialogButtonBox;
    class QLabel;
    class dialogTest : public QDialog
    {
        Q_OBJECT
    
    public:
        dialogTest(QWidget *parent = nullptr);
    
    private:
        QPushButton* one, *two, *three;
        QLabel* label, *btnLabel;
        QDialogButtonBox* dbBox;
    };
    #endif // DIALOGTEST_H
    

    dialogTest.cpp:

    #include "dialogtest.h"
    #include <QPushButton>
    #include <QLabel>
    #include <QDialogButtonBox>
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QMessageBox>
    
    dialogTest::dialogTest(QWidget *parent)
        : QDialog(parent)
    {
        one = new QPushButton(tr("&One"));
        two = new QPushButton(tr("&Two"));
        three = new QPushButton(tr("T&hree"));
        dbBox = new QDialogButtonBox(QDialogButtonBox::Ok);
        label = new QLabel(tr("Button Clicked:\n\r"));
        btnLabel = new QLabel;
    
        QHBoxLayout* hLayout = new QHBoxLayout;
        hLayout->addWidget(one);
        hLayout->addWidget(two);
        hLayout->addWidget(three);
    
        QVBoxLayout* vLayout = new QVBoxLayout;
        vLayout->addLayout(hLayout);
        vLayout->addWidget(label);
        vLayout->addWidget(btnLabel);
        vLayout->addWidget(dbBox);
    
        setLayout(vLayout);
    
       connect(dbBox, &QDialogButtonBox::clicked, this, &dialogTest::accept);
       connect(one,   &QPushButton::clicked, [this]() { btnLabel->setText("One"); });
       connect(two,   &QPushButton::clicked, [this]() { btnLabel->setText("Two"); });
       connect(three, &QPushButton::clicked, [this]() { btnLabel->setText("Three"); });
    }
    

    main.cpp:

    #include "dialogtest.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        dialogTest w;
        w.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2
      • lowercase class name - not a bug, but unorthodox
      • multiple pointers not initialized with nullptr in header file
      • connect statements contain a lambda but no control object (see https://github.com/KDE/clazy/blob/master/docs/checks/README-connect-3arg-lambda.md)
      • user-visible strings not enclosed in tr() calls (in lambdas)
      • code duplication in lambdas. Better use something like:
      auto notify = [this]() {
        auto button = qobject_cast<QPushButton*>(sender());
        btnLabel->setText(button->text());
      };
      

      (Z(:^

      Q 1 Reply Last reply
      6
      • sierdzioS sierdzio
        • lowercase class name - not a bug, but unorthodox
        • multiple pointers not initialized with nullptr in header file
        • connect statements contain a lambda but no control object (see https://github.com/KDE/clazy/blob/master/docs/checks/README-connect-3arg-lambda.md)
        • user-visible strings not enclosed in tr() calls (in lambdas)
        • code duplication in lambdas. Better use something like:
        auto notify = [this]() {
          auto button = qobject_cast<QPushButton*>(sender());
          btnLabel->setText(button->text());
        };
        
        Q Offline
        Q Offline
        qcoderpro
        wrote on last edited by
        #3

        @sierdzio
        Thank you.

        auto notify = this {
        auto button = qobject_cast<QPushButton*>(sender());
        btnLabel->setText(button->text());
        };

        This doesn't show anything!

        sierdzioS 1 Reply Last reply
        0
        • Q qcoderpro

          @sierdzio
          Thank you.

          auto notify = this {
          auto button = qobject_cast<QPushButton*>(sender());
          btnLabel->setText(button->text());
          };

          This doesn't show anything!

          sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          @qcoderpro said in Code review:

          @sierdzio
          Thank you.

          auto notify = this {
          auto button = qobject_cast<QPushButton*>(sender());
          btnLabel->setText(button->text());
          };

          This doesn't show anything!

          Possibly it needs to be done in a proper slot and not a lambda function.

          (Z(:^

          Q 1 Reply Last reply
          0
          • sierdzioS sierdzio

            @qcoderpro said in Code review:

            @sierdzio
            Thank you.

            auto notify = this {
            auto button = qobject_cast<QPushButton*>(sender());
            btnLabel->setText(button->text());
            };

            This doesn't show anything!

            Possibly it needs to be done in a proper slot and not a lambda function.

            Q Offline
            Q Offline
            qcoderpro
            wrote on last edited by
            #5

            @sierdzio

            Possibly it needs to be done in a proper slot and not a lambda function.

            And that slot is gonna be called each time any of those buttons is clicked. So once again three repetitive connections!

            sierdzioS 1 Reply Last reply
            0
            • Q qcoderpro

              @sierdzio

              Possibly it needs to be done in a proper slot and not a lambda function.

              And that slot is gonna be called each time any of those buttons is clicked. So once again three repetitive connections!

              sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              @qcoderpro said in Code review:

              @sierdzio

              Possibly it needs to be done in a proper slot and not a lambda function.

              And that slot is gonna be called each time any of those buttons is clicked. So once again three repetitive connections!

              But only single implementation ;-) Now you have 3.

              (Z(:^

              Q 1 Reply Last reply
              1
              • sierdzioS sierdzio

                @qcoderpro said in Code review:

                @sierdzio

                Possibly it needs to be done in a proper slot and not a lambda function.

                And that slot is gonna be called each time any of those buttons is clicked. So once again three repetitive connections!

                But only single implementation ;-) Now you have 3.

                Q Offline
                Q Offline
                qcoderpro
                wrote on last edited by
                #7

                @sierdzio
                Alright.

                Thanks for the link. What does "a context object" there completely mean please? I know in my example it mean the receiver, "btnLabel", but does it mean the object which receives the signal? Then why "a context object" and not "the receiver object"?

                1 Reply Last reply
                0
                • sierdzioS Offline
                  sierdzioS Offline
                  sierdzio
                  Moderators
                  wrote on last edited by
                  #8

                  Whatever object is meaningful in the context. This is used to disconnect the slot when necessary. In your case, code is executed in this (your dialog), so I'd use that as context object.

                  (Z(:^

                  1 Reply Last reply
                  2
                  • Q Offline
                    Q Offline
                    qcoderpro
                    wrote on last edited by qcoderpro
                    #9

                    I initialized all pointers in the header with "nullptr" and created a private slot:

                    private slots:
                        void printButton();
                    

                    Then changed the implementation to this:

                    dialogTest::dialogTest(QWidget *parent)
                        : QDialog(parent)
                    {
                        one = new QPushButton(tr("&One"));
                        two = new QPushButton(tr("&Two"));
                        three = new QPushButton(tr("T&hree"));
                        dbBox = new QDialogButtonBox(QDialogButtonBox::Ok);
                        label = new QLabel(tr("Button Clicked:\n\r"));
                        btnLabel = new QLabel;
                    
                        QHBoxLayout* hLayout = new QHBoxLayout;
                        hLayout->addWidget(one);
                        hLayout->addWidget(two);
                        hLayout->addWidget(three);
                    
                        QVBoxLayout* vLayout = new QVBoxLayout;
                        vLayout->addLayout(hLayout);
                        vLayout->addWidget(label);
                        vLayout->addWidget(btnLabel);
                        vLayout->addWidget(dbBox);
                    
                        setLayout(vLayout);
                    
                       connect(dbBox, &QDialogButtonBox::clicked, this, &dialogTest::accept);
                       connect(one, &QPushButton::clicked, this, &dialogTest::printButton);
                       connect(two, &QPushButton::clicked, this, &dialogTest::printButton);
                       connect(three, &QPushButton::clicked, this, &dialogTest::printButton);
                    }
                    
                    void dialogTest::printButton()
                    {
                        auto button = qobject_cast<QPushButton*>(sender());
                        btnLabel->setText(button->text());
                    }
                    
                    • Is it all OK now, please?
                    • When the button "one" is clicked, the string "&One" is shown, including the ampersand!
                    • The destructor is removed because all widgets are children of the top-level widget which is created on the stack, so there's nothing to be deleted manually, hence no memory leak.
                    • If we explain what the line below in the "printButton()" slot means in simple language, we would say:
                    auto button = qobject_cast<QPushButton*>(sender());
                    

                    Here "sender" returns a pointer to the object which called the slot (here a QPushButton), then that pointer is cast to <QPushButton*> and finally used to initialize "button". A shade vague!

                    Pl45m4P sierdzioS 2 Replies Last reply
                    0
                    • Q qcoderpro

                      I initialized all pointers in the header with "nullptr" and created a private slot:

                      private slots:
                          void printButton();
                      

                      Then changed the implementation to this:

                      dialogTest::dialogTest(QWidget *parent)
                          : QDialog(parent)
                      {
                          one = new QPushButton(tr("&One"));
                          two = new QPushButton(tr("&Two"));
                          three = new QPushButton(tr("T&hree"));
                          dbBox = new QDialogButtonBox(QDialogButtonBox::Ok);
                          label = new QLabel(tr("Button Clicked:\n\r"));
                          btnLabel = new QLabel;
                      
                          QHBoxLayout* hLayout = new QHBoxLayout;
                          hLayout->addWidget(one);
                          hLayout->addWidget(two);
                          hLayout->addWidget(three);
                      
                          QVBoxLayout* vLayout = new QVBoxLayout;
                          vLayout->addLayout(hLayout);
                          vLayout->addWidget(label);
                          vLayout->addWidget(btnLabel);
                          vLayout->addWidget(dbBox);
                      
                          setLayout(vLayout);
                      
                         connect(dbBox, &QDialogButtonBox::clicked, this, &dialogTest::accept);
                         connect(one, &QPushButton::clicked, this, &dialogTest::printButton);
                         connect(two, &QPushButton::clicked, this, &dialogTest::printButton);
                         connect(three, &QPushButton::clicked, this, &dialogTest::printButton);
                      }
                      
                      void dialogTest::printButton()
                      {
                          auto button = qobject_cast<QPushButton*>(sender());
                          btnLabel->setText(button->text());
                      }
                      
                      • Is it all OK now, please?
                      • When the button "one" is clicked, the string "&One" is shown, including the ampersand!
                      • The destructor is removed because all widgets are children of the top-level widget which is created on the stack, so there's nothing to be deleted manually, hence no memory leak.
                      • If we explain what the line below in the "printButton()" slot means in simple language, we would say:
                      auto button = qobject_cast<QPushButton*>(sender());
                      

                      Here "sender" returns a pointer to the object which called the slot (here a QPushButton), then that pointer is cast to <QPushButton*> and finally used to initialize "button". A shade vague!

                      Pl45m4P Offline
                      Pl45m4P Offline
                      Pl45m4
                      wrote on last edited by Pl45m4
                      #10

                      @qcoderpro

                      In addition you could rename your class, so that it stars with an upper case ( @sierdzio said that at the beginning as well)
                      It's not wrong, but code convention: class names start with upper case, then camel case. Variable names start with lower case letter.


                      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                      ~E. W. Dijkstra

                      1 Reply Last reply
                      0
                      • Q qcoderpro

                        I initialized all pointers in the header with "nullptr" and created a private slot:

                        private slots:
                            void printButton();
                        

                        Then changed the implementation to this:

                        dialogTest::dialogTest(QWidget *parent)
                            : QDialog(parent)
                        {
                            one = new QPushButton(tr("&One"));
                            two = new QPushButton(tr("&Two"));
                            three = new QPushButton(tr("T&hree"));
                            dbBox = new QDialogButtonBox(QDialogButtonBox::Ok);
                            label = new QLabel(tr("Button Clicked:\n\r"));
                            btnLabel = new QLabel;
                        
                            QHBoxLayout* hLayout = new QHBoxLayout;
                            hLayout->addWidget(one);
                            hLayout->addWidget(two);
                            hLayout->addWidget(three);
                        
                            QVBoxLayout* vLayout = new QVBoxLayout;
                            vLayout->addLayout(hLayout);
                            vLayout->addWidget(label);
                            vLayout->addWidget(btnLabel);
                            vLayout->addWidget(dbBox);
                        
                            setLayout(vLayout);
                        
                           connect(dbBox, &QDialogButtonBox::clicked, this, &dialogTest::accept);
                           connect(one, &QPushButton::clicked, this, &dialogTest::printButton);
                           connect(two, &QPushButton::clicked, this, &dialogTest::printButton);
                           connect(three, &QPushButton::clicked, this, &dialogTest::printButton);
                        }
                        
                        void dialogTest::printButton()
                        {
                            auto button = qobject_cast<QPushButton*>(sender());
                            btnLabel->setText(button->text());
                        }
                        
                        • Is it all OK now, please?
                        • When the button "one" is clicked, the string "&One" is shown, including the ampersand!
                        • The destructor is removed because all widgets are children of the top-level widget which is created on the stack, so there's nothing to be deleted manually, hence no memory leak.
                        • If we explain what the line below in the "printButton()" slot means in simple language, we would say:
                        auto button = qobject_cast<QPushButton*>(sender());
                        

                        Here "sender" returns a pointer to the object which called the slot (here a QPushButton), then that pointer is cast to <QPushButton*> and finally used to initialize "button". A shade vague!

                        sierdzioS Offline
                        sierdzioS Offline
                        sierdzio
                        Moderators
                        wrote on last edited by sierdzio
                        #11

                        @qcoderpro said in Code review:

                        • Is it all OK now, please?

                        Looks fine to me.

                        • When the button "one" is clicked, the string "&One" is shown, including the ampersand!

                        Ah, that's bad. Well, then you can probably go back to your original solution :-( Or, there is a chance that sender()->property("text").toString() will return it without ampersand (and no need for a cast!), but I don't know.

                        • The destructor is removed because all widgets are children of the top-level widget which is created on the stack, so there's nothing to be deleted manually, hence no memory leak.

                        Fine.

                        • If we explain what the line below in the "printButton()" slot means in simple language, we would say:
                        auto button = qobject_cast<QPushButton*>(sender());
                        

                        Here "sender" returns a pointer to the object which called the slot (here a QPushButton), then that pointer is cast to <QPushButton*> and finally used to initialize "button". A shade vague!

                        It might be unclear to people who do not know Qt, yes. The sender() method is a very special kind of method. But to anybody who has used Qt for a while, this is perfectly understandable.

                        (Z(:^

                        Q 1 Reply Last reply
                        0
                        • sierdzioS sierdzio

                          @qcoderpro said in Code review:

                          • Is it all OK now, please?

                          Looks fine to me.

                          • When the button "one" is clicked, the string "&One" is shown, including the ampersand!

                          Ah, that's bad. Well, then you can probably go back to your original solution :-( Or, there is a chance that sender()->property("text").toString() will return it without ampersand (and no need for a cast!), but I don't know.

                          • The destructor is removed because all widgets are children of the top-level widget which is created on the stack, so there's nothing to be deleted manually, hence no memory leak.

                          Fine.

                          • If we explain what the line below in the "printButton()" slot means in simple language, we would say:
                          auto button = qobject_cast<QPushButton*>(sender());
                          

                          Here "sender" returns a pointer to the object which called the slot (here a QPushButton), then that pointer is cast to <QPushButton*> and finally used to initialize "button". A shade vague!

                          It might be unclear to people who do not know Qt, yes. The sender() method is a very special kind of method. But to anybody who has used Qt for a while, this is perfectly understandable.

                          Q Offline
                          Q Offline
                          qcoderpro
                          wrote on last edited by
                          #12

                          @sierdzio

                          there is a chance that sender()->property("text").toString() will return it without ampersand (and no need for a cast!), but I don't know.

                          With or without a cast, the error below turns up:
                          error: calling 'property' with incomplete return type 'QVariant'
                          Optimistically, there's a way to solve it and not ruin what we've done from the first place where I used three implementations! :|

                          It might be unclear to people who do not know Qt, yes. The sender() method is a very special kind of method. But to anybody who has used Qt for a while, this is perfectly understandable.

                          Do you mean that is the exact "sender" as the first parameter in the Q_OBJECT::connection!? Yes, I think!

                          sierdzioS 1 Reply Last reply
                          0
                          • J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #13

                            personally I would prefer multiple lambdas over the use of sender()

                            e5abd79e-e6aa-4e2b-9941-864d545d9865-image.png


                            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                            Q: What's that?
                            A: It's blue light.
                            Q: What does it do?
                            A: It turns blue.

                            1 Reply Last reply
                            1
                            • Q qcoderpro

                              @sierdzio

                              there is a chance that sender()->property("text").toString() will return it without ampersand (and no need for a cast!), but I don't know.

                              With or without a cast, the error below turns up:
                              error: calling 'property' with incomplete return type 'QVariant'
                              Optimistically, there's a way to solve it and not ruin what we've done from the first place where I used three implementations! :|

                              It might be unclear to people who do not know Qt, yes. The sender() method is a very special kind of method. But to anybody who has used Qt for a while, this is perfectly understandable.

                              Do you mean that is the exact "sender" as the first parameter in the Q_OBJECT::connection!? Yes, I think!

                              sierdzioS Offline
                              sierdzioS Offline
                              sierdzio
                              Moderators
                              wrote on last edited by
                              #14

                              @qcoderpro said in Code review:

                              error: calling 'property' with incomplete return type 'QVariant'

                              #include <QVariant>

                              (Z(:^

                              Q 1 Reply Last reply
                              1
                              • sierdzioS sierdzio

                                @qcoderpro said in Code review:

                                error: calling 'property' with incomplete return type 'QVariant'

                                #include <QVariant>

                                Q Offline
                                Q Offline
                                qcoderpro
                                wrote on last edited by qcoderpro
                                #15

                                @sierdzio

                                Probably you mean this:

                                void dialogTest::printButton()
                                {
                                     btnLabel->setText(sender()->property("text").toString());
                                }
                                

                                Still with the ampersands!

                                @J-Hilk

                                personally I would prefer multiple lambdas over the use of sender()

                                I used both versions below:

                                connect(one, &QPushButton::clicked, this, [this]() { btnLabel->setText("&One"); });
                                 connect(two, &QPushButton::clicked, this,  [this]() { btnLabel->setText(two->text()); });
                                   
                                

                                Still with the ampersands!

                                1 Reply Last reply
                                0
                                • Q Offline
                                  Q Offline
                                  qcoderpro
                                  wrote on last edited by qcoderpro
                                  #16

                                  Not a bug?
                                  If it is, how to report that?

                                  mrjjM 1 Reply Last reply
                                  0
                                  • Q qcoderpro

                                    Not a bug?
                                    If it is, how to report that?

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

                                    @qcoderpro
                                    Hi
                                    Its not a bug. When the text contains a &, a shortcut is made for it but its not removed and not
                                    shown. So when you ask for its text() , its still included.

                                    Q 1 Reply Last reply
                                    1
                                    • mrjjM mrjj

                                      @qcoderpro
                                      Hi
                                      Its not a bug. When the text contains a &, a shortcut is made for it but its not removed and not
                                      shown. So when you ask for its text() , its still included.

                                      Q Offline
                                      Q Offline
                                      qcoderpro
                                      wrote on last edited by
                                      #18

                                      @mrjj
                                      Hi,

                                      and not shown. So when you ask for its text() , its still included.

                                      It's what the programmer needs, to be included but "not shown". In the example above, it's shown, while it mustn't! It can clearly be a bug I think.

                                      Pl45m4P 1 Reply Last reply
                                      0
                                      • Q qcoderpro

                                        @mrjj
                                        Hi,

                                        and not shown. So when you ask for its text() , its still included.

                                        It's what the programmer needs, to be included but "not shown". In the example above, it's shown, while it mustn't! It can clearly be a bug I think.

                                        Pl45m4P Offline
                                        Pl45m4P Offline
                                        Pl45m4
                                        wrote on last edited by Pl45m4
                                        #19

                                        @qcoderpro said in Code review:

                                        It can clearly be a bug I think

                                        The button text contains the & to create the shortcut. So why should btn->text() not return the full text with the ampersand?
                                        btn->text() just returns the QString which is the displayed button text (without any pre-processing). Only QPushButton (i.e. its base class QAbtractButton) converts & into the shortcut functionality and for this you need the ampersand in your button text. The text-getter does not know about this, so the actual text with ampersand is returned.

                                        Another example:
                                        If you inspect HTML with a texteditor, you will see <br> and no line break, because the text editor doesn't interpret this as line break, it just shows the raw UTF8 (or whatever) encoded text.


                                        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                        ~E. W. Dijkstra

                                        Q 1 Reply Last reply
                                        2
                                        • Pl45m4P Pl45m4

                                          @qcoderpro said in Code review:

                                          It can clearly be a bug I think

                                          The button text contains the & to create the shortcut. So why should btn->text() not return the full text with the ampersand?
                                          btn->text() just returns the QString which is the displayed button text (without any pre-processing). Only QPushButton (i.e. its base class QAbtractButton) converts & into the shortcut functionality and for this you need the ampersand in your button text. The text-getter does not know about this, so the actual text with ampersand is returned.

                                          Another example:
                                          If you inspect HTML with a texteditor, you will see <br> and no line break, because the text editor doesn't interpret this as line break, it just shows the raw UTF8 (or whatever) encoded text.

                                          Q Offline
                                          Q Offline
                                          qcoderpro
                                          wrote on last edited by
                                          #20

                                          @Pl45m4

                                          With this we have two options: either "not to use shortcuts" or "have the text including the ampersand"! Neither is wanted to me.
                                          To me, the code behind "setText" should've been designed so that it could process the text and omit the ampersands when showing.

                                          Do you have a better way?

                                          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