Whazzaaaapp? So, let’s turn our geek mode on now. For today’s post, the theme is about Qt. So, lately I’ve been in a huge need for a feature like NotifyPropertyChanged in .NET (C#). For you who don’t know what it is, it’s some kind of mechanism for a variable to notify other components that its value has been changed, and the other components will behave accordingly. This is a huge advantage if you have a lot of GUI components that are dependent on some certain variables (like visibility, enability, and stuff).
However, I couldn’t find any equivalence of this thing on Qt and I need to have this feature for primitive types (integer, boolean, string, etc). Since Qt is kinda big on SIGNAL and SLOT, so this was the first solution that came up to my mind, making a new class for each primitive type. I know, maybe it would be better if I made template classes instead, but the template class is not working with QObject, which is necessary for SIGNAL and SLOT. I’ve found some workarounds here, but I think the solution with observer is a huge amount of work, since I can’t connect it to the slot the the GUI components already have. So, I did it the brute force way, for every primitive class that I might need, I made a corresponding class.
I tested them, and they’re working just fine and it’s easy to use as well. All you need to do in your code is to connect the variable with whatever component you want to connect it with. Let’s say I want to connect a string with a label. It will go like this:
connect(&mstr, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));
If there’s somewhere in your code that the mstr value is changed, the text on ui->label will be changed as well. You might think that “Oh Andru come oon, it’s only one extra line to change the text. What’s the huge deal of this feature?” Well imagine if you’re changing the variable in various places, it means that you have to add that one extra line every single time the string is changed and it’s just pain in the ass.
And of course, I have made for other types as well: double, float, boolean, and integer. For my current use, the signals give the original type as well as the QString representation. For example:
connect(&mint, SIGNAL(valueChanged(QString)), ui->label, SLOT(setText(QString)));
connect(&mint, SIGNAL(valueChanged(int)), ui->label, SLOT(setNum(int)));
The implementation is very easy, it would take you no time to implement it yourself, but I thought it would be unnecessary time being wasted if I already implemented it, right? So, it’s just one header file (mmodel.h), all implementations are inline. And it can be downloaded here. And as a bonus, I included a little widget project to show you how it works. Even though it’s an easy peasy work, but please credit me if you’re using it in your application. All questions are welcome. I hope this helps.
And if you happen to know better solution than this, please inform me. I would love to know it.