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. Interesting effect with tr().arg()
Qt 6.11 is out! See what's new in the release blog

Interesting effect with tr().arg()

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 5 Posters 6.6k Views 1 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.
  • VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by
    #5

    I discussed in the past this and also the season why you should only use arg(QString) and not the other overloads

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    C 1 Reply Last reply
    2
    • joeQJ joeQ

      @ChrisVT Hi,Friend,Welcome.

      You can write some test code, to find why. It is interesting.

      Do not omit Intermediate results.

      You will clear well from following snippet:

      #include <QCoreApplication>
      
      #include <QtCore/QDebug>
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          qDebug() << QObject::tr("%1%2%3"); /// %1%2%3
          qDebug() << QObject::tr("%1%2%3").arg("A"); /// A%2%3
      
          qDebug() << QObject::tr("%2%3").arg("A"); ///A%3
      
          qDebug() << QObject::tr("%1%2%3").arg("A").arg("%2A"); /// A%2A%3
          qDebug() << QObject::tr("%1%2%3").arg("A").arg("%2A").arg("B"); /// ABA%3
          // To replace First %, is %1=>A, result is tr(A%2%3).arg(%2A).arg(B) 
          // In Result To replace First %, is %2=>%2, result is (A%2A%3).arg(B)
          // In Result To replace First %, is %2=>B, result is ABA%3
      
          return a.exec();
      }
      
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #6

      @joeQ
      I still don't get how this behaviour is anything to do with using QObject::tr(), in your examples and this thread title? I can't test because I don't use C++, but wouldn't your examples behave just the same if you used QString in place of QObject::tr? The arg()s are evaluated after the tr(), not before, aren't they?

      1 Reply Last reply
      1
      • JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #7

        Further to what I have written above, and to @VRonin 's post:

        ISTM that you should never use qString.arg().arg(). The chained args, which work on the substituted result from the previous arg() calls, are far too dangerous. [You wouldn't use C's sprint(format) with a non-literal format string for the same kind of reason, would you?]

        Like with sprintf, or repeated replaces or regular expression substitutions, you can only afford to use a substituter which works from a single, original string specifying what to do, not one affected by a previous substitution. You need a function which does multiple substitutions at the same time, not one after the other, to be safe.

        So I don't see/where is Qt's QString::argList() function, so you can go like: QString("%1%2%3")::argList(arg1, arg2, arg3), which is what you need to do?

        VRoninV 1 Reply Last reply
        0
        • JonBJ JonB

          @ChrisVT
          Firstly, I can't see how this can have anything to do with tr() function. As per http://doc.qt.io/qt-5/qobject.html#tr, QObject::tr() simply returns a QString, only then does it evaluate the .arg()s, so the whole thing is simply QString::arg() calls, forget about tr().

          • Check what plain tr("%1%2%3") returns?
          • Check what QString("%1%2%3").arg("A").arg("%2A").arg("B") returns?
          C Offline
          C Offline
          ChrisVT
          wrote on last edited by
          #8

          @JonB Correct, this has nothing to do with tr(). This was just the way I used it in my original code, and I didn't remove it. Sorry. The problem also occurs with QString.

          1 Reply Last reply
          1
          • JonBJ JonB

            Further to what I have written above, and to @VRonin 's post:

            ISTM that you should never use qString.arg().arg(). The chained args, which work on the substituted result from the previous arg() calls, are far too dangerous. [You wouldn't use C's sprint(format) with a non-literal format string for the same kind of reason, would you?]

            Like with sprintf, or repeated replaces or regular expression substitutions, you can only afford to use a substituter which works from a single, original string specifying what to do, not one affected by a previous substitution. You need a function which does multiple substitutions at the same time, not one after the other, to be safe.

            So I don't see/where is Qt's QString::argList() function, so you can go like: QString("%1%2%3")::argList(arg1, arg2, arg3), which is what you need to do?

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #9

            @JonB said in Interesting effect with tr().arg():

            You need a function which does multiple substitutions at the same time, not one after the other, to be safe.

            πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘

            @JonB said in Interesting effect with tr().arg():

            which is what you need to do?

            Actually it's very easy to solve the problem at hand: tr("%1%2%3").arg(QStringLiteral("A"),QStringLiteral("%2A"),QStringLiteral("B"))

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            JonBJ 1 Reply Last reply
            2
            • VRoninV VRonin

              @JonB said in Interesting effect with tr().arg():

              You need a function which does multiple substitutions at the same time, not one after the other, to be safe.

              πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘πŸ‘

              @JonB said in Interesting effect with tr().arg():

              which is what you need to do?

              Actually it's very easy to solve the problem at hand: tr("%1%2%3").arg(QStringLiteral("A"),QStringLiteral("%2A"),QStringLiteral("B"))

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #10

              @VRonin
              .arg() takes a list of arguments?

              VRoninV 1 Reply Last reply
              0
              • JonBJ JonB

                @VRonin
                .arg() takes a list of arguments?

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #11

                Yes, up to 9: http://doc.qt.io/qt-5/qstring.html#arg-21

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                JonBJ 1 Reply Last reply
                2
                • VRoninV VRonin

                  Yes, up to 9: http://doc.qt.io/qt-5/qstring.html#arg-21

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #12

                  @VRonin
                  Yeah, I just saw that, that's what I call "cheating" :)
                  Are the %numbers limited to 9 in the format string?
                  Where is QString::argv(arrayOfArgs) ? ;-)

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    I discussed in the past this and also the season why you should only use arg(QString) and not the other overloads

                    C Offline
                    C Offline
                    ChrisVT
                    wrote on last edited by
                    #13

                    Thanks for all the responses - very insightful!

                    @VRonin This also happens with QStrings:
                    qDebug() << QString("%1%2%3").arg("A").arg("%2A").arg("B"); -> "ABA%3"
                    qDebug() << QString("%1%2%3").arg(QString("A")).arg(QString("%2A")).arg(QString("B")); -> "ABA%3"
                    But yes, implicit type conversion can be very hard to figure out. Been there!

                    @joeB Good advice about using the arglist instead, but
                    (a) this only works for QStrings, not for numerical formats, and
                    (b) Qt offers the ability to use chained args which MOSTLY work.
                    I was incorrectly assuming that arg(a).arg(b) should be the same as .arg(a,b) for constant QStrings a and b. I'll still say it's not all that intuitive that it isn't.

                    JonBJ 1 Reply Last reply
                    1
                    • C ChrisVT

                      Thanks for all the responses - very insightful!

                      @VRonin This also happens with QStrings:
                      qDebug() << QString("%1%2%3").arg("A").arg("%2A").arg("B"); -> "ABA%3"
                      qDebug() << QString("%1%2%3").arg(QString("A")).arg(QString("%2A")).arg(QString("B")); -> "ABA%3"
                      But yes, implicit type conversion can be very hard to figure out. Been there!

                      @joeB Good advice about using the arglist instead, but
                      (a) this only works for QStrings, not for numerical formats, and
                      (b) Qt offers the ability to use chained args which MOSTLY work.
                      I was incorrectly assuming that arg(a).arg(b) should be the same as .arg(a,b) for constant QStrings a and b. I'll still say it's not all that intuitive that it isn't.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #14

                      @ChrisVT
                      I love things which "MOSTLY" work :)

                      Be aware, if you are going to use "numerical formats" as you say then, as @VRonin pointed out in the post he referred to, these will not be localed. If you care about that, you must format them to localed strings in the first place, then you can pass them to the list-arg() because they are now strings.

                      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