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. SplashScreen stay on TaskManager
QtWS25 Last Chance

SplashScreen stay on TaskManager

Scheduled Pinned Locked Moved Unsolved General and Desktop
splashscreentask manager
29 Posts 3 Posters 9.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    QtA_
    wrote on last edited by
    #13

    nope,..:( still active.

    #include <QApplication>
    #include <QSplashScreen>
    #include <QTimer>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QSplashScreen *splash=new QSplashScreen;
        splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
        splash->show();
        QTimer::singleShot(2500,splash,SLOT(close()));
        QTimer::singleShot(2500,splash,SLOT(quit()));
    
        return a.exec();
        return a.quit();
    
    }
    
    mrjjM 1 Reply Last reply
    0
    • Q QtA_

      nope,..:( still active.

      #include <QApplication>
      #include <QSplashScreen>
      #include <QTimer>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          QSplashScreen *splash=new QSplashScreen;
          splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
          splash->show();
          QTimer::singleShot(2500,splash,SLOT(close()));
          QTimer::singleShot(2500,splash,SLOT(quit()));
      
          return a.exec();
          return a.quit();
      
      }
      
      mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #14

      @QtA_
      You are asking it wrongly :)

      QTimer::singleShot(2500,splash,SLOT(quit())); <<<< wrong object. should be &app

      you are asking the timer to call quit() on splash, which splash dont have.

      QTimer::singleShot(2500,&app,SLOT(quit()));

      Update:
      Also
      The return statement will make it leave a function
      so

      return a.exec();
      return a.quit(); <<< u can never, ever get here :)

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        QtA_
        wrote on last edited by
        #15

        Thank you very much !! :)
        so i've added:

        QTimer::singleShot(2500,&a,SLOT(quit()));
        

        and removed

        return a.exec();
        

        seem to work fine now :)

        Question...

        why do I need to put time delay on quit if already the time done ?
        I mean,..

        QTimer::singleShot(2500,&a,SLOT(quit()));
        

        must be

        QTimer::singleShot(0,&a,SLOT(quit()));
        

        ?

        mrjjM 1 Reply Last reply
        0
        • Q QtA_

          Thank you very much !! :)
          so i've added:

          QTimer::singleShot(2500,&a,SLOT(quit()));
          

          and removed

          return a.exec();
          

          seem to work fine now :)

          Question...

          why do I need to put time delay on quit if already the time done ?
          I mean,..

          QTimer::singleShot(2500,&a,SLOT(quit()));
          

          must be

          QTimer::singleShot(0,&a,SLOT(quit()));
          

          ?

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

          @QtA_
          Hi
          Np.

          Does it display long enough with
          QTimer::singleShot(0,&a,SLOT(quit())); ?

          Then its ok.

          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            QtA_
            wrote on last edited by
            #17

            ok ...I've change the close by the quit.
            instead adding a new line. :)

            Thanks again for all your help.
            Angie xx

            mrjjM 1 Reply Last reply
            0
            • Q QtA_

              ok ...I've change the close by the quit.
              instead adding a new line. :)

              Thanks again for all your help.
              Angie xx

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

              @QtA_
              Np. Have fun programming. :)

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on last edited by Chris Kawa
                #19

                You don't need to force the app quit. It's not very flexible in the long run. By default Qt app quits automatically when a last window is closed. This is controlled in two places: on application level with setQuitOnLastWindowClosed (the default is true, so no need to change that). The other place is at the widget level with an attribute Qt::WA_QuitOnClose. This attribute is by default enabled for top level windows i.e. widgets with flag Qt::Window or Qt::Dialog except for certain types, including menus, tooltips and splashscreen.

                Since a splashscreen is all you have you can just turn the attribute back on:

                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    QSplashScreen *splash = new QSplashScreen;
                    splash->setAttribute(Qt::WA_QuitOnClose);  // <-- the relevant line
                    splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                    splash->show();
                    QTimer::singleShot(2500,splash,SLOT(close()));
                    return a.exec();
                }
                

                Btw. Technically this code leaks memory as you never delete the splash instance. To keep it clean you have couple of options:

                • manually delete the splash after the call to exec
                • add WA_DeleteOnClose attribute to the splash
                • (the easiest and recommended) just create the splash instance on the stack:
                QSplashScreen splash;
                splash.setAttribute(Qt::WA_QuitOnClose);
                splash.setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                splash.show();
                QTimer::singleShot(2500,&splash,SLOT(close()));
                
                mrjjM 1 Reply Last reply
                2
                • Chris KawaC Chris Kawa

                  You don't need to force the app quit. It's not very flexible in the long run. By default Qt app quits automatically when a last window is closed. This is controlled in two places: on application level with setQuitOnLastWindowClosed (the default is true, so no need to change that). The other place is at the widget level with an attribute Qt::WA_QuitOnClose. This attribute is by default enabled for top level windows i.e. widgets with flag Qt::Window or Qt::Dialog except for certain types, including menus, tooltips and splashscreen.

                  Since a splashscreen is all you have you can just turn the attribute back on:

                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                      QSplashScreen *splash = new QSplashScreen;
                      splash->setAttribute(Qt::WA_QuitOnClose);  // <-- the relevant line
                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                      splash->show();
                      QTimer::singleShot(2500,splash,SLOT(close()));
                      return a.exec();
                  }
                  

                  Btw. Technically this code leaks memory as you never delete the splash instance. To keep it clean you have couple of options:

                  • manually delete the splash after the call to exec
                  • add WA_DeleteOnClose attribute to the splash
                  • (the easiest and recommended) just create the splash instance on the stack:
                  QSplashScreen splash;
                  splash.setAttribute(Qt::WA_QuitOnClose);
                  splash.setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                  splash.show();
                  QTimer::singleShot(2500,&splash,SLOT(close()));
                  
                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by
                  #20

                  @Chris-Kawa
                  Much better with WA_QuitOnClose, indeed. :)

                  Do you know if QSplashScreen can do anything special compared to a plain QWidget in terms
                  of her overall goal? ( sort of fancy launcher )

                  Im not sure if a custom widget is not more fun later when she wants animations and fade in/out effects etc. Of Course she can derive from QSplashScreen but I do wonder if it
                  give anything of benefit for this use case. ?

                  1 Reply Last reply
                  0
                  • Q Offline
                    Q Offline
                    QtA_
                    wrote on last edited by
                    #21

                    Thank you guys,,...
                    it seem to work,..

                    however..many questions in my little brain..

                    splash name is my variable right ?
                    so may I redefine it many times ?

                    #include <QApplication>
                    #include <QSplashScreen>
                    #include <QTimer>
                    
                    int main(int argc, char *argv[])
                    {
                        QApplication a(argc, argv);
                        QSplashScreen *splash = new QSplashScreen;
                        splash->setAttribute(Qt::WA_QuitOnClose);  // <-- the relevant line
                        splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                        splash->show();
                        QTimer::singleShot(2500,splash,SLOT(close()));
                        
                        splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                        splash->show();
                        QTimer::singleShot(2500,splash,SLOT(close()));
                        
                        return a.exec();
                    }
                    

                    seem it keep always the last image...

                    1 Reply Last reply
                    0
                    • Chris KawaC Offline
                      Chris KawaC Offline
                      Chris Kawa
                      Lifetime Qt Champion
                      wrote on last edited by Chris Kawa
                      #22

                      @mrjj QSplashScreen is pretty basic. It's not well suited for any sort of animations. The easiest route for that would be, indeed, a plain old widget and overriding its paintEvent. Deriving from QSplashScreen would just get in your way.

                      @QtA_ You're thinking in line, while what happens is event driven. This code QTimer::singleShot(2500,splash,SLOT(close())); doesn't "wait" for 2.5 seconds. It just schedules the slot to fire in 2.5 seconds and moves on immediately. So this:

                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                      splash->show();
                      QTimer::singleShot(2500,splash,SLOT(close()));
                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                      

                      is just the same as this:

                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png"));
                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                      splash->show();
                      QTimer::singleShot(2500,splash,SLOT(close()));
                      

                      To make it work like you want to you need to schedule the switch to happen some time later, e.g.

                      splash->setPixmap(QPixmap ("C:/Users/public/test/Logo.png")); //set initial image
                      QTimer::singleShot(1000, [&]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); }); //change it after a second
                      QTimer::singleShot(2000, [&]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo2.png")); }); //change it again after 2 seconds etc.
                      
                      splash->show();
                      QTimer::singleShot(2500,splash,SLOT(close()));
                      
                      1 Reply Last reply
                      2
                      • Q Offline
                        Q Offline
                        QtA_
                        wrote on last edited by QtA_
                        #23

                        ok,...that work great !
                        my PNG animation is now done.. :) thank you.

                        However,..there is few questions if you dont mind.
                        is the [&] mean to execute what is in the bracket ? {}

                        I understand what i'm doing...but I do not understand yet how, when and why to put sometime bracket, [] sometime <> sometime "" or {}
                        i'm a little lost on when to use it..
                        is there any tutorial who explain this syllabus ?
                        Thanks again for all your help :)

                        mrjjM 1 Reply Last reply
                        0
                        • Q QtA_

                          ok,...that work great !
                          my PNG animation is now done.. :) thank you.

                          However,..there is few questions if you dont mind.
                          is the [&] mean to execute what is in the bracket ? {}

                          I understand what i'm doing...but I do not understand yet how, when and why to put sometime bracket, [] sometime <> sometime "" or {}
                          i'm a little lost on when to use it..
                          is there any tutorial who explain this syllabus ?
                          Thanks again for all your help :)

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

                          @QtA_ said in SplashScreen stay on TaskManager:
                          Hi

                          is the [&] mean to execute what is in the bracket ? {}

                          Yes its a c++ lambda. Think of it as "in place" function.

                          QTimer::singleShot(1000, [&]
                          {
                          //this is the function body
                          splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                          }
                          );

                          I understand what i'm doing...but I do not understand yet how, when and why to put sometime bracket, [] sometime <> sometime "" or {}

                          Oh,  there are many different uses, depending on context.
                          { } is often used as a block.
                          if (something)  {
                          // line 1
                          // line 2
                          } 
                          --
                          void somefunc() {
                          }
                          -----------------------
                          [] is used with array or lists. 
                          (and also the lambda syntax)
                          int list[1000];
                          int num=list[1];
                          -----------------------
                          The <> is often seen with templates. Templates are special c++ thing that allows any type to be used. the compiler will generate the needed code for all used types.
                          std::vector<int> mylist; // list of ints.
                          

                          So its hard to fully answer as its used in many contexts. So you better just ask :)

                          Q 1 Reply Last reply
                          0
                          • mrjjM mrjj

                            @QtA_ said in SplashScreen stay on TaskManager:
                            Hi

                            is the [&] mean to execute what is in the bracket ? {}

                            Yes its a c++ lambda. Think of it as "in place" function.

                            QTimer::singleShot(1000, [&]
                            {
                            //this is the function body
                            splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                            }
                            );

                            I understand what i'm doing...but I do not understand yet how, when and why to put sometime bracket, [] sometime <> sometime "" or {}

                            Oh,  there are many different uses, depending on context.
                            { } is often used as a block.
                            if (something)  {
                            // line 1
                            // line 2
                            } 
                            --
                            void somefunc() {
                            }
                            -----------------------
                            [] is used with array or lists. 
                            (and also the lambda syntax)
                            int list[1000];
                            int num=list[1];
                            -----------------------
                            The <> is often seen with templates. Templates are special c++ thing that allows any type to be used. the compiler will generate the needed code for all used types.
                            std::vector<int> mylist; // list of ints.
                            

                            So its hard to fully answer as its used in many contexts. So you better just ask :)

                            Q Offline
                            Q Offline
                            QtA_
                            wrote on last edited by QtA_
                            #25

                            @mrjj said in SplashScreen stay on TaskManager:

                            @QtA_ said in SplashScreen stay on TaskManager:
                            Hi

                            is the [&] mean to execute what is in the bracket ? {}

                            Yes its a c++ lambda. Think of it as "in place" function.

                            QTimer::singleShot(1000, [&]
                            {
                            //this is the function body
                            splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png"));
                            }
                            );

                            I understand what i'm doing...but I do not understand yet how, when and why to put sometime bracket, [] sometime <> sometime "" or {}

                            Oh,  there are many different uses, depending on context.
                            { } is often used as a block.
                            if (something)  {
                            // line 1
                            // line 2
                            } 
                            --
                            void somefunc() {
                            }
                            -----------------------
                            [] is used with array or lists. 
                            (and also the lambda syntax)
                            int list[1000];
                            int num=list[1];
                            -----------------------
                            The <> is often seen with templates. Templates are special c++ thing that allows any type to be used. the compiler will generate the needed code for all used types.
                            std::vector<int> mylist; // list of ints.
                            

                            So its hard to fully answer as its used in many contexts. So you better just ask :)

                            Thank you very much !
                            Not sure to understand more....but with practice...i'll figure out.. :)
                            first,..need to learn what LAMBDA is.. lol ! :)

                            in fact,..I use Qt beacause I thought that it had an option for dialog transparency..
                            so by putting an image with invisible dialog will do the trick.. :( bad thinking..

                            1 Reply Last reply
                            0
                            • mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #26

                              Hi
                              No.
                              Well lambdas are nameless functions. Its like a normal function but has a funny syntax
                              to be allowed to written "in place".
                              https://blog.feabhas.com/2014/03/demystifying-c-lambdas/
                              So where places you would use a pointer to a function, you can now directly give it the function there.

                              .I use Qt beacause I thought that it had an option for dialog transparency.

                              Well it does support transparency but it can vary between platforms and windows managers.
                              :)

                              1 Reply Last reply
                              0
                              • Chris KawaC Offline
                                Chris KawaC Offline
                                Chris Kawa
                                Lifetime Qt Champion
                                wrote on last edited by Chris Kawa
                                #27

                                @mrjj Lambdas are not anonymous functions. They are anonymous structures with operator(). That's an important distinction, because how would you explain captures on a function?

                                @QtA_ LONG READ AHEAD WARNING. Here's a lambdas 101, with examples of the standard algorithms (that was their first use).

                                Lets say you have a vector of ints: std::vector<int> v {1,5,3,7};.
                                Now you want to sort it. Easy right? You just do std::sort(v.begin(), v.end());. Done.
                                Now you want to sort it in reverse. Well there's a template for it: std::sort(v.begin(), v.end(), std::greater<int>());, but lets say for a moment that there isn't (or you want to implement that template). How would that be done?

                                In C++98 you had to provide your own function:

                                bool foo(int a, int b) { return b < a; }
                                std::sort(v.begin(), v.end(), foo);
                                

                                or a functor ( a structure with operator()):

                                struct Foo {
                                bool operator()(int a, int b) const { return b < a; }
                                };
                                std::sort(v.begin(), v.end(), Foo());
                                

                                std::greater<int> is just such structure, except it is templated so it can be used for anything, not just ints :

                                template <typename T> struct Foo {
                                bool operator()(const T& a, const T& b) const { return b < a; }
                                };
                                std::sort(v.begin(), v.end(), Foo<int>());
                                

                                The problem with this is that you had to put these functions or structs somewhere and there often wasn't a good place for it, so they ended up in some utils.h bag of unrelated functions.

                                Lambdas were introduced to solve this problem and shorten the syntax. Now you can create such a structure in place. A syntax of a lambda is [](){} (yes, because there were too few brackets in the language so they used all of them ;) ). So now you can write:

                                std::sort(v.begin(), v.end(), [](int a, int b){ return b < a;});
                                

                                One line. Lovely. What happens behind the courtains is that compiler secretly generates something like this:

                                struct _SomeHorribleGeneratedName_{
                                bool operator()(int a, int b) const { return b < a; }
                                };
                                std::sort(v.begin(), v.end(), _SomeHorribleGeneratedName_());
                                

                                The name the lambda gets is never visible to you, so that's why this is called an anonymous struct. So it's the same as before: () is the argument list, {} is the body of the function. But what's the [] for then?

                                Let's take another example:
                                Lets say that you now want to find an element 3 in the vector: auto it = std::find(v.begin(), v.end(), 3);. Done. Easy.
                                Lets say you want to find first element, that is greater than 2. Now you have to use one of those funky functors:

                                struct Foo {
                                bool operator()(int a) const { return a > 2; }
                                };
                                auto it = std::find_if(v.begin(), v.end(), Foo());
                                

                                How about a lambda?:

                                auto it = std::find_if(v.begin(), v.end(), [](int a){ return a > 2; });
                                

                                Cool. But lets say 2 is not a constant, but some parameter you want to pass to it:

                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), [](int a){ return a > param; }); //this won't compile :(
                                }
                                

                                We've got a problem here, because param is not in the scope of the lambda. Remember, that the compiler does this:

                                struct _SomeHorribleGeneratedName_ {
                                bool operator()(int a) const { return a > param; } //what is param?
                                };
                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_());
                                }
                                

                                Here's where the [] comes in. It's a capture expression. Here you can "capture" values from the scope into the lambda, so it knows them:

                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), [param](int a){ return a > param; }); //ok!
                                }
                                

                                This makes the compiler generate something like this:

                                struct _SomeHorribleGeneratedName_ {
                                   _SomeHorribleGeneratedName_(int p) : param(p) {}
                                   bool operator()(int a) const { return a > param; }
                                   int param;
                                };
                                
                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_(param));
                                }
                                

                                So it creates instance of the lambda and passes the captured value with a constructor parameter so that it can be used inside the lambda.
                                But what if the param was not int but some large object that we didn't want to copy (or it couldn't be copied)? We can also capture by reference:

                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), [&param](int a){ return a > param; }); //see the & before the param name?
                                }
                                

                                and this makes compiler generate something like this:

                                struct _SomeHorribleGeneratedName_ {
                                   _SomeHorribleGeneratedName_(int& p) : param(p) {}
                                   bool operator()(int a) const { return a > param; }
                                   int& param; //the param is now a reference
                                };
                                
                                void foo(int param) {
                                    auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_(param));
                                }
                                

                                In the previous post we used something like [&] for the capture list. What does that mean? It's a shortcut meaning "capture everything we use inside the lambda by reference". It's so you don't have to list all the values you use. So this:

                                QTimer::singleShot(1000, [&]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                

                                is the same as this, but shorter:

                                QTimer::singleShot(1000, [&splash]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                

                                What if we wanted to capture everything by value (copy)? The syntax is [=], so we could write:

                                QTimer::singleShot(1000, [splash]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                

                                or

                                QTimer::singleShot(1000, [=]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                

                                ant this would copy the splash pointer instead of creating a reference to it.
                                If you have couple of params you want to capture, some by value, some by reference, you can mix and match: [param1, &param2, param3]. param1 and param3 will be captured by value and param2 by reference.

                                That's pretty much all you'll need to know about lambdas most of the time. There are a couple more related topics - mutable lambdas and generalized lambdas (lambdas that create template structs, whoa!), but this was suppose to be 101 so...

                                Hope this wasn't too boring ;)

                                mrjjM 1 Reply Last reply
                                2
                                • Chris KawaC Chris Kawa

                                  @mrjj Lambdas are not anonymous functions. They are anonymous structures with operator(). That's an important distinction, because how would you explain captures on a function?

                                  @QtA_ LONG READ AHEAD WARNING. Here's a lambdas 101, with examples of the standard algorithms (that was their first use).

                                  Lets say you have a vector of ints: std::vector<int> v {1,5,3,7};.
                                  Now you want to sort it. Easy right? You just do std::sort(v.begin(), v.end());. Done.
                                  Now you want to sort it in reverse. Well there's a template for it: std::sort(v.begin(), v.end(), std::greater<int>());, but lets say for a moment that there isn't (or you want to implement that template). How would that be done?

                                  In C++98 you had to provide your own function:

                                  bool foo(int a, int b) { return b < a; }
                                  std::sort(v.begin(), v.end(), foo);
                                  

                                  or a functor ( a structure with operator()):

                                  struct Foo {
                                  bool operator()(int a, int b) const { return b < a; }
                                  };
                                  std::sort(v.begin(), v.end(), Foo());
                                  

                                  std::greater<int> is just such structure, except it is templated so it can be used for anything, not just ints :

                                  template <typename T> struct Foo {
                                  bool operator()(const T& a, const T& b) const { return b < a; }
                                  };
                                  std::sort(v.begin(), v.end(), Foo<int>());
                                  

                                  The problem with this is that you had to put these functions or structs somewhere and there often wasn't a good place for it, so they ended up in some utils.h bag of unrelated functions.

                                  Lambdas were introduced to solve this problem and shorten the syntax. Now you can create such a structure in place. A syntax of a lambda is [](){} (yes, because there were too few brackets in the language so they used all of them ;) ). So now you can write:

                                  std::sort(v.begin(), v.end(), [](int a, int b){ return b < a;});
                                  

                                  One line. Lovely. What happens behind the courtains is that compiler secretly generates something like this:

                                  struct _SomeHorribleGeneratedName_{
                                  bool operator()(int a, int b) const { return b < a; }
                                  };
                                  std::sort(v.begin(), v.end(), _SomeHorribleGeneratedName_());
                                  

                                  The name the lambda gets is never visible to you, so that's why this is called an anonymous struct. So it's the same as before: () is the argument list, {} is the body of the function. But what's the [] for then?

                                  Let's take another example:
                                  Lets say that you now want to find an element 3 in the vector: auto it = std::find(v.begin(), v.end(), 3);. Done. Easy.
                                  Lets say you want to find first element, that is greater than 2. Now you have to use one of those funky functors:

                                  struct Foo {
                                  bool operator()(int a) const { return a > 2; }
                                  };
                                  auto it = std::find_if(v.begin(), v.end(), Foo());
                                  

                                  How about a lambda?:

                                  auto it = std::find_if(v.begin(), v.end(), [](int a){ return a > 2; });
                                  

                                  Cool. But lets say 2 is not a constant, but some parameter you want to pass to it:

                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), [](int a){ return a > param; }); //this won't compile :(
                                  }
                                  

                                  We've got a problem here, because param is not in the scope of the lambda. Remember, that the compiler does this:

                                  struct _SomeHorribleGeneratedName_ {
                                  bool operator()(int a) const { return a > param; } //what is param?
                                  };
                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_());
                                  }
                                  

                                  Here's where the [] comes in. It's a capture expression. Here you can "capture" values from the scope into the lambda, so it knows them:

                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), [param](int a){ return a > param; }); //ok!
                                  }
                                  

                                  This makes the compiler generate something like this:

                                  struct _SomeHorribleGeneratedName_ {
                                     _SomeHorribleGeneratedName_(int p) : param(p) {}
                                     bool operator()(int a) const { return a > param; }
                                     int param;
                                  };
                                  
                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_(param));
                                  }
                                  

                                  So it creates instance of the lambda and passes the captured value with a constructor parameter so that it can be used inside the lambda.
                                  But what if the param was not int but some large object that we didn't want to copy (or it couldn't be copied)? We can also capture by reference:

                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), [&param](int a){ return a > param; }); //see the & before the param name?
                                  }
                                  

                                  and this makes compiler generate something like this:

                                  struct _SomeHorribleGeneratedName_ {
                                     _SomeHorribleGeneratedName_(int& p) : param(p) {}
                                     bool operator()(int a) const { return a > param; }
                                     int& param; //the param is now a reference
                                  };
                                  
                                  void foo(int param) {
                                      auto it = std::find_if(v.begin(), v.end(), _SomeHorribleGeneratedName_(param));
                                  }
                                  

                                  In the previous post we used something like [&] for the capture list. What does that mean? It's a shortcut meaning "capture everything we use inside the lambda by reference". It's so you don't have to list all the values you use. So this:

                                  QTimer::singleShot(1000, [&]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                  

                                  is the same as this, but shorter:

                                  QTimer::singleShot(1000, [&splash]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                  

                                  What if we wanted to capture everything by value (copy)? The syntax is [=], so we could write:

                                  QTimer::singleShot(1000, [splash]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                  

                                  or

                                  QTimer::singleShot(1000, [=]{ splash->setPixmap(QPixmap ("C:/Users/public/test/Logo1.png")); })
                                  

                                  ant this would copy the splash pointer instead of creating a reference to it.
                                  If you have couple of params you want to capture, some by value, some by reference, you can mix and match: [param1, &param2, param3]. param1 and param3 will be captured by value and param2 by reference.

                                  That's pretty much all you'll need to know about lambdas most of the time. There are a couple more related topics - mutable lambdas and generalized lambdas (lambdas that create template structs, whoa!), but this was suppose to be 101 so...

                                  Hope this wasn't too boring ;)

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

                                  @Chris-Kawa
                                  Yes, You are right. was too oversimplified wrong explanation.
                                  Was aiming to explain what lambdas are without going into class and operator () details
                                  but now she get the grand tour :) so it will all be clear \o/

                                  Very nice 101. Should be on the wiki :)

                                  1 Reply Last reply
                                  0
                                  • Q Offline
                                    Q Offline
                                    QtA_
                                    wrote on last edited by
                                    #29

                                    wow,..is that supposed to help ? LOL ! :)
                                    Thank you very much for all explaination,..I really need to make tests with this.
                                    maybe one day I'll be one of yours..(guru) :)

                                    for now I cut/Paste your explaination on my notebook :)
                                    thanks again.

                                    Angie xx

                                    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