Advance Tutorial on QT Usage
-
Hi,
I'm really trying to get good at Qt. It is times that Qt needs me to put in some crazy parameters, but I have difficulties finding out how to use it by just looking at Qt's resources. Here is an example:
setTextColor(const QColor & color);
Here is my documentation on how to use this from Qt's resources:
http://doc.qt.io/qt-5/qtextedit.html#setTextColor
Now the correct way of using this is:
setTextColor(QColor(20, 30, 40)); this is just a way of doing it with RGB
or
setTextColor(QColor("blue")); this is another example, but with blue.
I didn't get there by looking at Qt's reference page. I searched Google and was able to find these examples. I'm sure that it is many other ways of doing this.
But my main question is where can I get the advance resources from Qt that will give me some insight into Qt's complex system for using its functions.
-
The docs in this particular case are pretty well written:
setTextColor
takes a single QColor argument. I hope that's clear.
Now you can click on the QColor param and go to the QColor docs:
QColor has several constructors, all of them described pretty well. Where's the confusion coming from?But my main question is where can I get the advance resources from Qt that will give me some insight into Qt's complex system for using its functions.
What complex system do you mean? Qt is mostly classes and functions. Usually simple c++ with bits of templates and macros. All documented.
-
Hi Chris,
I have to say thank-you for being involved in the forum and supplying assistance. I took a C++ class in college recently and it was a college-level introductory course. We didn't go as far as using that language to create useful applications or games. Looking at the curriculum, it appears that in order to get good at creating useful applications, you have to teach yourself. The curriculum didn't have Qt, Opengl, UE4, SMFL, and a bunch of other useful stuff. So this summer, I been studying different API's.
Now, looking at that parameter, const QColor & color, not knowing any better, I assumed that I had to create a QColor reference object and make it constant. Something like this:
QColor &color = new QColor();
then manipulate the object and then set it to a constant and then finally pass it as a parameter. That was the first thing that I thought of, even though it didn't seem right. What was the actual way was to almost-like pass a constructor as a value. That wasn't something that I would had thought of, because I only think about creating a constructor is when I'm about to use a new class.
So based on what you heard so far, it is clear that I might need to take a look at some of Qt resources on advance programming. The good thing about Qt is that it range from medium difficulty to a very high ceiling and I would love to be able to take advantage of all that Qt has to offer, even the stuff that is up there.
Thanks again Chris :)
-
Passing arguments by const reference is not a Qt specific thing. It's a general C++ way of passing arguments.
Sounds like you should rather go back to some of the C++ concepts before going ahead with Qt.
Starting to develop more complex applications before getting a solid grip on the language basics will surely lead to some hard to shake off bad habits and difficult to diagnose problems (like memory leaks or performance drops).There's a c++ section on the forum and we're here to help, but I'd suggest a good c++ book to start you off, and then some tutorials or the Super FAQ on the official ISO C++ site.
-
This post is deleted!
-
@ChrisW
You can also read
http://www.bogotobogo.com/cplusplus/files/c-gui-programming-with-qt-4-2ndedition.pdf
which is a free Qt4 book.
Gives a good intro to the overall system. -
Thanks for your advice!!
One big question that I do have that I can't really find an answer to is how was I suppose to know that const QColor &c meant for me to pass in a function? Looking at some tutorials, you can pass in other things. When I went to reference page of QColor, it just spoke about the class. This is important to me because I want Qt reference to be my one-stop for everything. I had to google search how to use one of the functions recently.
Another question that I have, which doesn't have anything to do with Qt, but this answer is non-existent on the internet. You're familiar with the main function in C++. It is a special function that a C++ program must have. There are other functions that I have seen from other API's such as UnrealScript, NinjaScript, and etc that uses special functions that don't behave as normal functions. For instance:
OnUpdateBar() function, which pretty much at like a loop. Basically, you write it as this:
OnUpdateBar(){
// Your code
}Basically, everytime price changes, everything in this function is ran.
So basically, functions receives code within the curly brackets. How do I go about writing such a special function?
-
I want Qt reference to be my one-stop for everything
It can be. At least in this particular case.
Lets break this down:
QColor has several constructors described here.
All listed constructors are:QColor() //1 QColor(int r, int g, int b, int a = 255) //2 QColor(QRgb color) //3 QColor(const QString & name) //4 QColor(const char * name) //5 QColor(const QColor & color) //6 QColor(Qt::GlobalColor color) //7
This means that you can create a QColor instance in any of these ways
QColor someColor; //1 QColor someColor(42, 53, 64, 75); //2 QColor someColor(0xFF6699AA); //3 QColor someColor(QString("cyan")); //4 QColor someColor("magenta"); //5 QColor someColor(someOtherColor); //6 QColor someColor(Qt::blue); //7
Ok, that's the first step.
The second is non-Qt related and has to do with c++ topic - argument passing. Let's look at this example of functions taking parameters of some type but in different ways:void f1(SomeType variable) { variable = 42; } void f2(SomeType& variable) { variable = 42; } void f3(const SomeType& variable) { variable = 42; } //this won't compile void f4(const SomeType& variable) { std::cout << variable; } //and then we can do: SomeType foo; //foo is passed "by value". It means it is copied to the inside of that function and a copy is modified. //The original foo is not modified f1(foo); //foo is passed "by reference". The foo variable is given another name (variable) but refers to the same place in memory as foo. //It is not a copy so when you modify "variable" you modify "foo" too. f2(foo); //foo is passed by "const reference". This is the same as above except any modification to the "variable" is forbidden. //Because we try to assign 42 to it it will not compile. f3(foo); //foo is passed by "const reference". This is the same as above but we don't try to write to the variable so it will compile. //Reading from "variable" is ok //This method is used for passing read-only variables to the functions. //Because it is passed by reference (no copy) it is very cheap f4(foo);
Ok, now that we have that there's a third topic - temporary variables. In above examples we created a variable foo and then passed it to a function. But we don't need to do that. We can simply create an unnamed temporary variable and pass that to the function:
SomeType foo; f1(foo); //we can do this instead: f1(SomeType());
We're almost there. There's just one more C++ feature that we need to have full picture here - implicit conversions. Lets say we have a class with a constructor that takes some text as a parameter. We also have a function that takes that class instance as a parameter like this:
class SomeType { public: SomeType(const char* text) { ... } }; void f(SomeType variable) { ... } //so we can do this: SomeType foo("hello world"); f(foo); //as we established above we can write this with an unnamed temporary variable: f(SomeType("hello world")); //although there is no function void f(const char*), c++ allows a single implicit type conversion //so it will create SomeType variable for us if we write the above like this: f("hello world");
So now that we have all that we can apply this knowledge to our little
setTextColor
example:QColor someColor("blue"); //we could use any of the constructors, I just chose this for example setTextColor(someColor); //or we could write: setTextColor(QColor("blue")); //or setTextColor("blue");
Another example:
QColor someColor(Qt::blue); setTextColor(someColor); //or we could write: setTextColor(QColor(Qt::blue)); //or setTextColor(Qt::blue);
As you can see the only Qt specific thing here is the list of possible QColor constructors and parameters. That is listed in the docs.
The rest is pure c++ and for that you should study the mentioned books, as there are a lot more explanations and examples. -
Your other question was about "special functions". Please don't compare c++ to other languages because things will work different in them. This is especially true for scripting languages like UnrealScript, which has very different concepts and can't be directly mapped to c++.
So sticking with c++: there are no special functions in this language. "main" is not special at all. It's a regular function like any other. The fact that it is the first function called in a program is just a convention, but there's nothing stopping you from calling it "mySuperFunction". the only difference is that the linker (the program that generates the executable file from your code) assumes that it is called "main", so if you change it to something else you need to tell it via some parameters. For the record - don't change it. I'm just saying you could if you wanted.
So in short - you asked how to create special functions. You can't because there is no such thing. There are just regular functions.The "OnUpdateBar" is not a loop. It is a concept known as "callback": in reaction to something happening some function is called. It can be realized in many many ways in c++. Qt has implemented it as a signal/slot mechanism. The docs cover it deeply but in short one class has a signal function and another one has slot function. Then you make a connection between that signal and slot. When something happens in first class and it emits a signal the slot function in the other one is called. for example:
QLineEdit* someLineEdit = ... //we create a QLineEdit instance QWidget* someWidget = ... //we create a QWidget instance // QLineEdit has a signal "textChanged" and QWidget has slot "setWindowTitle" so we can connect them QObject::connect(someLineEdit, &QLineEdit::textChanged, someWidget, &QWidget::setWindowTitle);
As for how you can create your own signals and slots see the small example in the docs I linked to before.
-
@Chris-Kawa said:
WoW!! I'm blown away by how helpful that was. I'm going to look at Qt's functions and see if I can apply my knowledge to all of its functions. It is one in particular that uses "|" inside the parameter and since you taught me how to fish, I should now be able to figure out what Qt was doing with that function.
And for special functions, thanks for the helpful advice. Just to mention, UnrealScript is not a scripting language despite having that "script" involved in its name--unless I'm not understanding what a scripting language is. My understanding is a language that doesn't need to be compiled such as PHP, Javascript, HTML, CSS, and others. UnrealScript is similar to Qt, but it is an API that makes game development easier. You can consider it as SFML or SDL on steroids and is for programmers that are serious about making powerful games with time efficiency in mind.
-
Please don't confuse languages with libraries. UnrealScript and C++ are languages. Qt is a C++ library and SDL is a C library.
UnrealScript is a scripting language. It compiles to a bytecode (just like for example JavaScript) that is then interpreted at runtime by an interpreter (written in C++ by the way) embedded into UDK executable.As for the "|" - this is again non-Qt concept. if you remember your logic classes there are a couple of boolean operators like "or" and "and".
These are expressed in C++ by operators||
and&&
. So for exampletrue || false == true
,true && false == false
.These operators have their binary counterparts
|
and&
that instead of comparing whole values compare each bit of the values so for example101 | 011 == 111
,101 && 011 == 001
. You can think of|
asany of
and&
asall of
. These bit operators are very useful for defining "flags" like this:const int Flag1 = 1; //1 is ..00000001 in binary const int Flag2 = 2; //2 is ..00000010 in binary const int Flag3 = 4; //4 is ..00000100 in binary const int Flag4 = 8; //8 is ..00001000 in binary //and so on...
Now if you want to pass a set of flags into a function you could do this like this:
void someFunction(bool isFlag1Set, bool isFlag2Set, bool isFlag3Set); //and call it someFunction(true, false, false)
but if you're gonna have 20 flags the function will be horrible (20 bool params!) and totally unreadable (what that 13th "true" meant again... ?) so it's a lot nicer to use a single argument to pass combined flags:
void someFunction(int flags); //and call it someFunction(0); //this passes no flags someFunction(Flag1); //this passes 1, which in binary is 0001 someFunction(Flag1 | Flag2); //this passes 1|2 == 3, which in binary is 0001|0010 == 0011 someFunction(Flag3 | Flag2); //this passes 4|2 == 6, which in binary is 0100|0010 == 0110
Inside the function you can inspect if a given flag is set by using the '&' operator like this:
// assuming Flag1|Flag2 was passed as the flag argument: bool isFlag1Set = (flags & Flag1) != 0; //which is 011 & 001 == 001, 001 != 0 so the result is true bool isFlag2Set = (flags & Flag2) != 0; //which is 011 & 010 == 010, 010 != 0 so the result is true bool isFlag3Set = (flags & Flag3) != 0; //which is 011 & 100 == 000, 000 == 0 so the result is false
Qt often uses this to pass various options as such flags, for example:
QLabel *label = ... label->setAlignment(Qt::AlignBottom | Qt::AlignRight);
In this case
Qt::AlignBottom
andQt::AlignRight
are flags just like in my example above.This is a short overview. Again, for more info I suggest hitting proper C++ books.
-
I like your knowledge and I want to be like you when I grow up. :)
This is a healthy situation to be in because I acknowledge that I'm not a C++ expert and willing to say incorrect things and instantly have it corrected. :)
I program in Java and C++, with syntaxes that are similar. We use API's to stand for classes; methods that stand for functions. I use API a lot because I get better results in Google when I use API instead, but they are interchangeable.
The reason why I thought that UnrealScript was API(or library) was because of this:
https://docs-origin.unrealengine.com/latest/INT/API/index.html
and that it was based off of C++ because of this:
https://docs.unrealengine.com/latest/INT/Programming/
it has C++ written all over it.
Thanks again for your thorough explanation. Also, were you an educator at one point? Very impressed at how you are familiar with binary, which is something that is used in Arduino programming and other hardware programming stuff. I'm sure other things too, but I don't think it is common to find someone that have a broad knowledge about everything unless they are an educator or just passionate about programming.