Creating working hyperlinks in Qt Quick Text

These days its fairly common that your UI designer walks up to you and asks to include web-style links in your desktop app.
Thanks to the fact that Qt Quick Text element supports HTML, you can say-

Text {
    anchors.centerIn: parent
    text: "To learn about KDE, <a href='http://www.kde.org'>click here</a>"
}

which results in-

Screenshot

Notice how nothing happens when you click on the link? This is because Qt Quick doesn’t open a browser by default, but lets you decide what to do by emitting the linkActivated signal which you can handle-

Text {
    anchors.centerIn: parent
    text: "To learn about KDE, <a href='http://www.kde.org'>click here</a>"
    onLinkActivated: Qt.openUrlExternally(link)
}

The link works now, but there’s another problem: you don’t see a hand cursor when hovering over the link. This is going to cause quite some confusion for your user. To fix this, use the following-

Text {
    anchors.centerIn: parent
    text: "To learn about KDE, <a href='http://www.kde.org'>click here</a>"
    onLinkActivated: Qt.openUrlExternally(link)

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.NoButton // we don't want to eat clicks on the Text
        cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
    }
}

Screenshot

Presto! You get a link with the correct hand cursor in Qt Quick.

The Web on QML – Part 2

This is a follow up on my first post about QML instead of HTML for a web experience, if you haven’t read it, I recommend you do so here.

After the demo showing the possibility to load QML files from the web, now it is time to see how we can actually build something useful out of this. I picked an example of a Flickr public gallery browser.

A Flickr photo browser app

The app basically lets you browse the latest few hundred public photos uploaded to flickr (accessing Flickr images over HTTP). You can find the demo’s code at github, which I am hosting at http://flickr.shaan7.info/ in order to serve ‘pages’ over HTTP to the QML browser.

Index Page

On the index page you can select between either a grid based view of the photos or a list based one where you can see the full titles of the photos.

l5N1k2o

The implementation of the index page looks uses the hyperlink element, you can either set a text or use custom QML items (in this case Image)-

import “http://qmlweb.shaan7.info/qmlweb&#8221;

Hyperlink {
url: ‘http://flickr.shaan7.info/List.qml&#8217;
Image {
anchors.fill: parent
source: ‘http://www.niscode.com/listicon.png&#8217;
}
}

Code reuse across List and Grid

While the List and Grid views look different in the presentation, they share couple of things-

Note: Normally if you have Foo.qml in the same directory, you can use it in another QML file by simple saying-

Foo {
}

The QML runtime automatically figures as its in the same directory. However, for remote URIs, QML does not do that and you need to provide a special file called qmldir with contents such as:

Foo Foo.qml
Magic MagicComponent.qml
ExtraMagic extras/Magic.qml

It is essentially hidden of course. For more info, see http://qt-project.org/doc/qt-5/qtqml-modules-qmldir.html

Reuse is handled the same way regular web browsers do it – caching resources that have been downloaded already.

The Flickr viewer app in use

Ah5MPN7 aiF6InA

And a video..

Code for flickr app

The code for the app is at https://github.com/shaan7/flickr-qmlweb

Additions to the library

This application also served to show us what features to implement. It now supports-

  • MouseCursor element – this lets you assign different mouse pointers to items. The app uses it to assign a Hand cursor on the thumbnails.
  • Hyperlink element – creates a text or custom hyperlink. Right now it only works with absolute URIs. This uses MouseCursor internally.

Additions to the browser

The browser now supports navigation, you can browse to custom URIs and go back in the history when required.
The code for the browser is at https://github.com/shaan7/qmlweb/

What Next?

Functional things to do for the browser and library

  • CSS equivalents?
  • Firefox/ Chrome plugins
  • Non functional issues (security, sandbox, etc).
  • Where do people help out / sign up?

The Web on QML

I was reading UI Markup Nirvana where Paul talks about the need to have a better markup technology than the HTML+CSS combo. Well, he is not alone, a lot of people want this and have made some success too. All these efforts were based on letting people write code in QML which will eventually run in a standard browser – hence called “QML for the Web”.

So far so good, I thought, but what about the other way round? You could write a lightweight container (which is a Qt app) which can load QML “pages” off the network and weave this with common web paradigms like hyperlinks. I tried it and https://github.com/shaan7/qmlweb/ is a result of that.

Playing with V-Play and QML

V-Play is a third-party game development platform built on top on Qt which allows game developers to quickly take their mockups to a playable game. V-Play achieves this by leveraging the power of QML by offering plugins and components which help in common game development tasks. These include plugins for Visual elements (such as Sprites), Networking modules to enable multiplayer interactions, Social Media/Monetization and so on.

 

 

Sample Games

Thanks to our friends at V-Play, I tried out some of their samples for cross-platform games and were quite impressed around the end results produced by trivial QML code. The first one I tried was the Flappy Bird example (thanks to the weirdo popularity of the game) listed at http://v-play.net/doc/howto-flappybird-game/ . With a bit of reading up of the components, it was quite easy to put together the pieces and get the game running.

 

Another example I found interesting was StackTheBox as it lets you try the physics engine for collisions, in this case between the boxes.

 

 

Documentation

Another brilliant aspect was the excellent documentation of each Component that the V-Play plugins provide. This plays a critical role because when you promise quick releases, having good documentation and examples is absolutely necessary. An example of this is the Facebook integration that has step-by-step instructions at http://v-play.net/doc/plugins1-facebook/ 

 

 

Finally

Those were the few things I got to play with during my evaluation period of the library, and it was quite fun. The selling point was ease of use and the drastic reduction in number of lines of QML code when using V-Play components for things like Monetization, Achievements etc. If some day I decide to create some crazy games, I’m sure where to look at :D

 

Under the Hood

 

Qt is a cross-platform application development framework for creating desktop and mobile applications with rich user interfaces. It supports all major platforms such as Linux, Mac OSX and Windows along with mobile platforms such as Android, iOS, Sailfish and Ubuntu Touch.

 

Qt Meta-object Language (QML) is a declarative language used to describe UI in a Qt application. The declaration uses JSON-like constructs with the ability to embed JavaScript code inline. The final UI is rendered on an OpenGL accelerated scene graph which allows for a smooth experience. A quick example would look like this-

 

import QtQuick 2.1

import QtQuick.Controls 1.0

 

ApplicationWindow {

   width: 300

   height: 300

   

   Rectangle {

       anchors.fill: parent

       color: colorTextBox.text

       

      TextField {

           id: colorTextBox

           anchors.centerIn: parent

       }

   }

}

This would display a text input field enclosed by a rectangle which changes color to whatever was typed in it-

QtQuick provides a collection of tools and components which developers can use in their applications. Examples would be UI components like Push Buttons etc or models which represent data from a remote source like the XmlListModel

 

 

[Linux] How to stop Skype from eating all your bandwidth

In other words, how to throttle and limit bandwidth that Skype uses on your Linux box.

The Problem

I use Skype to talk to few friends and relatives who won't use anything else and Hangouts isn't that convenient anyway. The problem is that there is no way on the Linux client to limit the bandwidth usage, in my case it ends up uploading way too high quality video than required. I had to limit it.

What didn't work

Solution 1Use tc to shape the traffic

I thought this will be easy, just use some service like iptables to shape traffic. Found that tc is one such tool and as long as you can match a traffic pattern, you can shape it (in our case, limit the bandwidth). However, searching through the web you will realize that matching Skype traffic isn't very easy and reliable. They do a pretty good job obfuscating the traffic. So this didn't help.

Solution 2 – Use squid as proxy server and limit traffic using it

Another way was to use squid's delay pools feature to limit traffic flowing through it and then tell Skype to use this. This seemed like a trivial solution as well, if Skype weren't a disobedient kid to ignore your proxy settings. Yes! you heard it right, Skype will just ignore your proxy settings if it can connect to the Internet without it.

The Solution

After hours of searching and hair pulling action, I came up with an addition to Solution 2 – use iptables to block access to skype. Now, iptables doesn't really have per application rules (like what people are used to from Windows Firewall etc) but it can filter on user/group. Using this, I did the following-

  1. Install and start squid
  2. Create a group called nonet
  3. Use the following iptables rules to block all communication for the group nonet, but still allow access to 127.0.0.1:3128 where squid runs (order is important)-
    • sudo iptables -A OUTPUT -p tcp -s 127.0.0.1 –dport 3128 -m owner –gid-owner nonet -j ACCEPT
    • sudo iptables -A OUTPUT -m owner –gid-owner nonet -j REJECT –reject-with icmp-net-unreachable
  4. Run Skype as the nonet group like this-
    • sudo -g nonet PULSE_LATENCY_MSEC=60 /usr/bin/skype
  5. Skype should not be able to login. Goto Options>Advanced and set the HTTPS proxy to point to squid (default 127.0.0.1 port 3128).
  6. Skype should now be able to login using the proxy (it takes a minute or two though). If not, try restarting Skype.

 

(Note that you don't even need to enable delay queues for squid to control the bandwidth, at least for me Skype doesn't go over 20KBps Upload/Download when using a proxy.)

Reuse docker images and save bandwidth

Lately, Docker has been creating a lot of fuss and I decided to give it a try. The website was easy to follow and the hello world example easy to setup.

The Problem

It was great to have a container setup for me automatically with a ubuntu base image running. All this in just few seconds. Well, assuming you have a blazingly fast Internet connection to download the image in few seconds. In any case, it makes sense for anyone to be able to reuse already downloaded files on one machine for the other machines. This is what I wanted to do, it didn't make sense for me to download the image on all of my machines.

The Solution

Initially I thought “well, its just a matter of copying the image file to the other machine and you're done”. Well, I soon realized that it might not be that straightforward as it is not just one image but different “layers” of images managed by AuFS.

Luckily, Docker provides a simple solution to do this -

user@machine1:~$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              12.04               8dbd9e392a96        9 months ago        128 MB
ubuntu              latest              8dbd9e392a96        9 months ago        128 MB
ubuntu              precise             8dbd9e392a96        9 months ago        128 MB
ubuntu              12.10               b750fe79269d        9 months ago        175.3 MB
ubuntu              quantal             b750fe79269d        9 months ago        175.3 MB

user@machine1:~$ sudo docker save ubuntu > ubuntu.tar

Now copy ubuntu.tar from machine1 to machine2 and follow these from machine2:

user@machine2:~$ cat ubuntu.tar | sudo docker load

user@machine2:~$ sudo docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              12.04               8dbd9e392a96        9 months ago        128 MB
ubuntu              latest              8dbd9e392a96        9 months ago        128 MB
ubuntu              precise             8dbd9e392a96        9 months ago        128 MB
ubuntu              12.10               b750fe79269d        9 months ago        175.3 MB
ubuntu              quantal             b750fe79269d        9 months ago        175.3 MB

Or, if you want a compressed tar,

user@machine1:~$ sudo docker save ubuntu | bzip2 > ubuntu.tar.bz2

Copy ubuntu.tar.bz2 from machine1 to machine2

user@machine2:~$ bunzip2 ubuntu.tar.bz2 –stdout | sudo docker load

Or, if your machines are connected by a network and you can use ssh,

user@machine1:~$ sudo docker save ubuntu | bzip2 | ssh  user@machine2 “cat > ubuntu.tar.bz2″

user@machine2:~$ bunzip2 ubuntu.tar.bz2 –stdout | sudo docker load

Hope that helps!

Akademy 2013 and la experiencia

[update: earlier, this was accidentally posted incomplete, this version is the complete one]

This year's gearheads' meetup was in Bilbao which is located in the Basque Country in Spain. The talks were very good and gave a good idea of whats going around in the Qt and KDE worlds. There were people taking Qt to new platforms and others getting your contacts more organized.

The talks

The first keynote was from Eva from EFF where she talked about how the recent revelations affect people outside the United States. Then, Kevin talked about how to use QWidget-widgets in QML, making life easier for developers. This was followed by updates on Qt on BlackBerry and story about the Mer Project and how essential they are in helping Free Software mobile platforms to funciton. Something special this Akademy, we had Jerome from the Razor project talk about the project, it goals and bits about how parts of LXDE were rewritten in Qt. There was also a talk on Plasma2 – the next version of KDE's workspaces which brings in the new feature where Plasma can dynamically load different shells (desktop, netbook, tablet etc).

I had a talk on Pair Programming with KDE where I shared the experience of me and few other KDE contributors working on code together. While there were many different things, the most important realization we had was that pairing was awesome to introduce new contributors to a project's codebase and good practices. (Also, I learnt to never, ever edit your already good slides just before your talk to screw them up :P )

On the second day, there were lightning talks by various people, a talk about KPeople – a new metacontact library and a pretty cool demo of dictation by Simon from Peter Grasch. We also had a group photo :)

BoFs

Other than the usual BoFs, there was a very interesting BoF this year around usability testing. Thanks to Björn and Jos, we had a session where people brought in their apps and others volunteered as users to find usability (to be more precise, learnability) issues. We had KScreen, Plasma Network Manager, Plasma Media Center and KStars as the applications and each of them had pretty useful results. There were countless ocassions where a developer would get amazed “omg! I thought that was obvious”.

There was also a BoF around the mentoring program the KDE organizes. We talked about how the programs were going on (and were being planned) and also some of the issues that came up this and the last year. At some point, there was the topic of Indian students being too naive, which is kinda true at times because of the way kids are brought up here. Most of the times, however, just pointing out their exact mistake and ways to improve will do the trick. I say that from personal experience (and I'm sure others will agree). Still, if you believe you've encountered someone who seems from another planet instead of an Asian subcontinent, don't hesitate to ask on #kde-in (or motivate the student to do so).

KDE Mentoring program BoF

There was also a BoF on Plasma Media Center where we explored ways of improvement and the road to the future. More details on Sinny's blog.

There were also some discussions of some magic that's gonna happen in KDE-India next year, but, for now, thats all we'll tell you :P

Win free copies of Packt’s Linux Shell Scripting Cookbook

I am pleased to announce that I have teamed up with Packt Publishing to organize a giveaway especially for you. Four lucky winners stand a chance to win few copies of the book. Keep reading to find out how you can be among the lucky ones.

The Prize

What you will learn from Linux Shell Scripting Cookbook, Second Edition

  • Master the art of crafting one-liner command sequence to perform text processing, digging data from files, backups to sysadmin tools, and a lot more

  • And if powerful text processing isn't enough, see how to make your scripts interact with the web-services like Twitter, Gmail

  • Explores the possibilities with the shell in a simple and elegant way – you will see how to effectively solve problems in your day to day life

What can you win?

  • 2 e-copies of Linux Shell Scripting Cookbook, Second Edition are up for grabs as well as 2 print copies will be available (for US or UK based address) or any other eBook of your choice from the Packt library.
     

What do I have to do?

 

Contest Rules:

  • 4 winners with maximum no. of posts will be selected by me or Packt.

  • Earliest reply/post will be given preference.

  • Contest open till 30-July-2013, so hurry up.

 

I’m going to Akademy 2013 !

After a long wait, I finally have my visa to Spain to attend Akademy 2013! If you haven't heard of it, Akademy is the annual summit of KDE where gearheads meet to plan the next steps to world domination. We talk about how to create beautiful free software for people to use and to enrich our vibrant community. I am also giving a talk on the fun, and sometimes weird times when I did some pair programming on some KDE software.

Sounds exciting? Well, its not too late, you can still register at http://akademy2013.kde.org/register.

Using QtMobility on SailfishOS SDK

Jolla's SailfishOS SDK was released quite some time back for Linux, OSX and Windows. I had tried it once during that time but only compiled some sample apps until I found some time recently to port one of my N9/Harmattan apps to Sailfish/Nemo.

The problem

The app needed to use the device's GPS system to know its coordinates for which I used QtMobility's location API. However, when trying to compile, the SDK wasn't able to find the QGeoPositionInfoSource header and I found that it was really missing from the SDK's include dir. In fact, the whole QtMobility module was missing.

The solution

SailfishOS SDK doesn't contain QtMobility by default, you have to install it manually. Luckily the SailfishOS SDK control center makes it easy.

  1. Click on the SailfishOS button on the leftmost toolbar in Qt Creator
  2. Goto Targets and click 'manage' in SailfishOS-i486-x86 (it might be different for you)
  3. Scroll down to qt-mobility-devel and install it.

Presto! Now you can use QtMobility in your application :)