Are you familiar with INotifyPropertyChanged in MVVM pattern on C#? And you are programming QT now? And somehow you need the MVVM pattern on Qt so you really miss that INotifyPropertyChanged on Qt? May be this blog post will fit you. 🙂
Disclaimer: This was from around two years ago. There might be better solution for this and we are happy to discuss about this with you. 😀
So, maybe if you read it in the history of Radyalabs, we were a company that was heavily focused on Windows Phone development, thus .NET Framework, specifically C#. Personally for me, one of the most beautiful things in C# is the interface INotifyPropertyChanged and all its friends. I imagine a lot of you are nodding with me in agreement. For those of you who don’t, try to look up MVVM pattern and you will see what I mean. You can use this pattern to solve a lot of problems, but basically 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).
About two years ago, I was working on Qt and somehow felt like I need the MVVM pattern in my application. I was so frustrated because I couldn’t find anything at the time. I couldn’t think of any other patterns that might have helped me. Considering that I only needed this pattern to be implemented on primitive types (integer, boolean, string, etc), I decided to “implement” it myself. Since Qt was (and still 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 have been better if I had made template classes instead, but the template class was not working with QObject, which was necessary for SIGNAL and SLOT. I’d found some workarounds with observer, however I noticed it was 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 have needed, I had 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 come on, 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. Not to mention this can easily be extended to TwoWay binding (though some value checking is necessary to avoid infinite loop of signal triggers).
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.
- Posted by admin
- On May 21, 2014
- 0 Comments