Fortune client/server example details
-
Hi all,
I'm meticulously studying this fortune client example for the time being and at times meet some issues regarding the code, by chance.
This first question is now about
QLatin1String
. I've sought info on the Web about this question but what I've read through that and Docs haven't been that vivid to remove the ambiguity of that type in my mind.
I know that: QLatin1String is a thin wrapper for plain, 8-bit C string. QString is a Unicode-aware string. Under the hood, it stores data as 16-bit characters. QString is a bit more expensive to construct than QLatin1String because the data is larger ("Hello" takes up 5 bytes in QLatin1String, but 10 bytes in QString). However, QString is much more powerful so it is used everywhere in the Qt API.In:
QString str = QLatin1String("localhost");
- Does it mean that now
str
contains 9 characters and its length is 18 bytes? - And if we use non-ascii literals instead of "localhost" that won't be inserted to the
str
, right? Because "QLatin1String" acts like a filter to accept only ascii characters? - Is using
QLatin1String
just because it's faster thanAString
in codes?
- Does it mean that now
-
@tomy said in Fortune client/server example details:
Does it mean that now str contains 9 characters and its length is 18 bytes?
No, the string contains 9 characters, the used memory for this string is 2*9 bytes (+ some more for the QString object itself)
And if we use non-ascii literals instead of "localhost" that won't be inserted to the str, right? Because "QLatin1String" acts like a filter to accept only ascii characters?
No, the string is interpreted as latin1 - if there are non-latin1 characters your resulting string will be messed up.
Is using QLatin1String just because it's faster than QString in codes?
QLatin1String is just used to avoid the conversion from an utf-8 string (which is the default when using the plain QString(const char*) ctor - the conversion from latin1 is simply faster. There are also specialized overloads which take a QLatin1String.
-
@tomy said in Fortune client/server example details:
Does it mean that now str contains 9 characters and its length is 18 bytes?
No, the string contains 9 characters, the used memory for this string is 2*9 bytes (+ some more for the QString object itself)
And if we use non-ascii literals instead of "localhost" that won't be inserted to the str, right? Because "QLatin1String" acts like a filter to accept only ascii characters?
No, the string is interpreted as latin1 - if there are non-latin1 characters your resulting string will be messed up.
Is using QLatin1String just because it's faster than QString in codes?
QLatin1String is just used to avoid the conversion from an utf-8 string (which is the default when using the plain QString(const char*) ctor - the conversion from latin1 is simply faster. There are also specialized overloads which take a QLatin1String.
@Christian-Ehrlicher, thanks.
latin1 characters
What are those latin1 characters?
(which is the default when using the plain QString(const char*) ctor
What do you mean by "ctor", please?
-
-
A question on the
void Client::readFortune()
function:In the line:
QTimer::singleShot(0, this, &Client::requestNewFortune);
the third parameter must be a const char* while here it's a void function "readFortune". Why please?And why not simply using
requestNewFortune();
in the function instead of that line? -
A question on the
void Client::readFortune()
function:In the line:
QTimer::singleShot(0, this, &Client::requestNewFortune);
the third parameter must be a const char* while here it's a void function "readFortune". Why please?And why not simply using
requestNewFortune();
in the function instead of that line?@tomy said in Fortune client/server example details:
A question on the
void Client::readFortune()
function:In the line:
QTimer::singleShot(0, this, &Client::requestNewFortune);
the third parameter must be a const char* while here it's a void function "readFortune". Why please?And why not simply using
requestNewFortune();
in the function instead of that line?Those are the choices https://doc.qt.io/qt-5/qtimer.html#static-public-members
You can use any of those. The choice is with you. -
A question on the
void Client::readFortune()
function:In the line:
QTimer::singleShot(0, this, &Client::requestNewFortune);
the third parameter must be a const char* while here it's a void function "readFortune". Why please?And why not simply using
requestNewFortune();
in the function instead of that line?@tomy said in Fortune client/server example details:
hird parameter must be a const char* while here it's a void function
that's a function pointer, so const char* holds true
see link of @koahnigAnd why not simply using requestNewFortune(); in the function instead of that line?
apparently requestNewFortune is supposed to be called not immediately but during the next event loop cycle.
A Timer with an interval of 0 will timeout as soon as event loop continues
-
@tomy said in Fortune client/server example details:
A question on the
void Client::readFortune()
function:In the line:
QTimer::singleShot(0, this, &Client::requestNewFortune);
the third parameter must be a const char* while here it's a void function "readFortune". Why please?And why not simply using
requestNewFortune();
in the function instead of that line?Those are the choices https://doc.qt.io/qt-5/qtimer.html#static-public-members
You can use any of those. The choice is with you.@koahnig
So it's seemingly using this version:singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
.@J-Hilk
that's a function pointer, so const char* holds trueIs a function pointer the same as a char pointer!?A Timer with an interval of 0 will timeout as soon as event loop continues
So it's pretty much equal to an immediate call of the function, not?
I also ought to read more about the event loop and its cycles. I thought there was merely one event loop starting from the execution of the project until it closes.
-
@koahnig
So it's seemingly using this version:singleShot(int msec, const QObject *receiver, PointerToMemberFunction method)
.@J-Hilk
that's a function pointer, so const char* holds trueIs a function pointer the same as a char pointer!?A Timer with an interval of 0 will timeout as soon as event loop continues
So it's pretty much equal to an immediate call of the function, not?
I also ought to read more about the event loop and its cycles. I thought there was merely one event loop starting from the execution of the project until it closes.
@tomy said in Fortune client/server example details:
So it's pretty much equal to an immediate call of the function, not?
nope, take this example
//myWidget.h class myWidget : public QObject { Q_OBJECT public: myWidget(QObject * parent = nullptr) : QObject(parent){} void sendSignal(){ emit printTime(QTime::currentTime().toString("hh.mm.ss.zzz"))); QTimer::singleShot(0,this, [=] ()->void{emit printTime(QTime::currentTime().toString("hh.mm.ss.zzz"));} ); } signals: void printTime(QString time); };
//main.cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); myWidget m; QObject::connect(&m, &myWidget::printTime, [=](QString time)->void{ qDebug() << "SIGNAL"<< time; }); m.sendSignal(); for(int i = 0; i < 0xFFFFFFF; i++){ if(i % 10000000 == 0) qDebug() << "busy" << i; } return a.exec(); }
-
@tomy said in Fortune client/server example details:
So it's pretty much equal to an immediate call of the function, not?
nope, take this example
//myWidget.h class myWidget : public QObject { Q_OBJECT public: myWidget(QObject * parent = nullptr) : QObject(parent){} void sendSignal(){ emit printTime(QTime::currentTime().toString("hh.mm.ss.zzz"))); QTimer::singleShot(0,this, [=] ()->void{emit printTime(QTime::currentTime().toString("hh.mm.ss.zzz"));} ); } signals: void printTime(QString time); };
//main.cpp int main(int argc, char *argv[]) { QApplication a(argc, argv); myWidget m; QObject::connect(&m, &myWidget::printTime, [=](QString time)->void{ qDebug() << "SIGNAL"<< time; }); m.sendSignal(); for(int i = 0; i < 0xFFFFFFF; i++){ if(i % 10000000 == 0) qDebug() << "busy" << i; } return a.exec(); }
@j-hilk
By this example I assume that
singleShot(0, ...
will be triggered when the next event loop finishes and executed after (here) 0 seconds (at once). So apparently we have many event loops throughout the project not only one starting fromapp.exec()
to the time of project closing.I searched the Web but couldn't find something special to the Qt event loop term explaining it clearly.
-
@j-hilk
By this example I assume that
singleShot(0, ...
will be triggered when the next event loop finishes and executed after (here) 0 seconds (at once). So apparently we have many event loops throughout the project not only one starting fromapp.exec()
to the time of project closing.I searched the Web but couldn't find something special to the Qt event loop term explaining it clearly.
@tomy said in Fortune client/server example details:
So apparently we have many event loops throughout the project not only one starting from app.exec() to the time of project closing.
yes and no,
You mainly have one event loop for your application, but you could force it to have more.See your program as one single file, you start at the top and you go down. You may jump all over the place via function calls, but eventually you end up at the end. If you don't, then you end up with the "unresponsive Window" error on desktops 😉
But when you're at the end, the event loop kicks in. It fetches possible events from the OS (mouse click for example) and schedules slots that are connected to signals - that are connected via QueueudConnection - to be executed, and tells the OS to redraw part of your Ui, if it changed.
-
@tomy said in Fortune client/server example details:
So apparently we have many event loops throughout the project not only one starting from app.exec() to the time of project closing.
yes and no,
You mainly have one event loop for your application, but you could force it to have more.See your program as one single file, you start at the top and you go down. You may jump all over the place via function calls, but eventually you end up at the end. If you don't, then you end up with the "unresponsive Window" error on desktops 😉
But when you're at the end, the event loop kicks in. It fetches possible events from the OS (mouse click for example) and schedules slots that are connected to signals - that are connected via QueueudConnection - to be executed, and tells the OS to redraw part of your Ui, if it changed.
@j-hilk
Thanks for the answer.
Let's get it straight!It's
main.cpp
where all Qt Widget/Quick projects start from when we hit Run.#include <QApplication> #include "client.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QApplication::setApplicationDisplayName(Client::tr("Fortune Client")); Client client; client.show(); return app.exec(); }
The first lines are creating a QApplication object with two arguments, then setting the window's display name. We then instantiate our class called Client. So these stages plus object's creation are carried out (as compile time stage supposedly) until control reaches show() - showing the project's UI -, and app.exec - starting executing the project (run-time stage). From this point, Qt event loop begins.
Now what are the cycles of it? How is the event loop divided into a number of cycles?