This week has been a roller-coaster ride for me. There were times when Wt just refused to be a good sport, times when we made great and wonderful progress and also times when I thought Wt wronged me, but turned out I did not understand it enough. As usualy, I have learned a lot new things about Wt, mostly concerning the graphical and user interface.
Interactivity
While developing a web app., it would be useful for you to know that clicking the button in a WContainerWidget WILL emit two clicked() signals, one from WContainerWidget and another from WPushButton (if you happen to connect both of them). I found out that to disable the propagation, you will need to use WPushButton::setPopup(true). Doing this will give you more room to attach signals.
WContainerWidget and WGridLayout
Most web app. has navigation bar as header. I tried to create a WGridLayout at the bottom of the header. This would mean using two WContainers. It didn’t work of course, because when you add more than one WContainerWidgets into root(), everything will get pulled up (*quoting Wt: children are always pushed to the top of the container), occupying the least space as possible. I needed the WGridLayout to fill up the whole screen automatically, and there isn’t a function that does this. In the end, I resorted to only one WContainerWidget and setting its layout which consists of the navigation bar and contents.
Implementing Drag and Drop
There is an example provided by Wt demonstrating its use, and it’s really simple to implement in any web application. I think most of the widgets can be dragged using setDraggable(). By default, the entire widget is dragged; and the widget disappears completely after drag! Unless, we provide another drag widget, which can be a WImage, or whatever. Too bad, there should be an option to drag the original widget without forcing it to disappear.
What can we achieve by drag and drop? It surprised me that there is a source() member function for WDropEvent. It returns the pointer to the dragged widget object! In the WDropEvent function, we can get the source widget id by simply event.source()->id()
We can also call any of its member functions.
Bad File Descriptor while Post-ing to Dropbox
After completing a basic Drive storage, I moved to implement the same thing using Dropbox APIs. That’s when I faced the long dreaded ‘bad file descriptor’ error in client callback function. At first, it seemed weird and creepy because the error goes on and off. Dr. Shawn pointed out that the http Client that I set up was not thread-safe. I was certainly clueless because I’ve been using the same standard Post format (similar to the Wt::Http::Client example). This problem only surfaced when Post-ing to Dropbox APIs. Although I yet to know how to make the client thread-safe, I manage to bypass the problem by adding ‘-t 1’ in command to use only 1 thread. Only setting it in Wt-config.xml will not work. So, the bright side is that we know it’s not supernatural occurrences, but simply thread-related.
2 Comments
Maisha · 2015-12-03 at 11:38
Keep going Jeunn Hao! I am learning progress of my parts through these 😀
That “bad file descriptor” is a terrible thing! Hope you solve it soon
Jeunn Hao Chong · 2015-12-09 at 12:11
Thanks Maisha 🙂