Showing posts with label Qt. Show all posts
Showing posts with label Qt. Show all posts

Tuesday, January 29, 2013

Planning Poker for BB10

Check out my new app, Planning Poker for BlackBerry 10. It's created using Qt and Cascades/QML. The source code, which is released under the Apache License v2.0, is available from the project page on Bitbucket.

The application features a clean, simple and Ad-free user interface for your agile planning sessions. Simply swipe between cards or pinch to pick one fast. Double tap to hide/unhide. Supports light and dark card theme.



Thursday, January 17, 2013

Informative list views in Cascades (BB10)

This post gives an example how you can present the user some informative text or controls when a list view is empty.

Typical scenarios where this may be desirable are:
  • When populating a list view with data from a network service.
    • Show a Fetch data button if the list view is empty.
    • Present any error that might occur while downloading/processing the data
  • Showing search result in a list view.
    • Present a No items found text to the user if the list view is empty.
In the example application I'm using an ArrayDataModel, but it should work for QListDataModel and GroupDataModel too. Unfortunately, it will not work with XmlDataModel because the class doesn't expose any function to query if the model is empty (at least not easily).

All of the data models mentioned above provides an isEmpty() function which can be used to check if the data model contain any items or not.

The example should speaks for itself, so without any further ado, here's the code:

import bb.cascades 1.0
Page {

    Container {
        layout: DockLayout {}

        ListView {
            dataModel: ArrayDataModel {
                id: model

                // Bindable property which tells if the
                // model is empty or not
                property bool empty: true

                // Populates model with dummy data
                function populate() {
                    for (var i = 0; i < 10; i++) {
                        append({'title' : 'Item #' + i})
                    }
                }

                // The following signal handlers updates
                // the empty property to correct state
                onItemAdded: empty = isEmpty()
                onItemRemoved: empty = isEmpty()
                onItemUpdated: empty = isEmpty()

                // You might see an 'unknown signal' error
                // in the QML-editor, guess it's a SDK bug.
                onItemsChanged: empty = isEmpty()
            }
        }

        // Only visible when data model is empty.
        // This should be declared after the ListView
        // to prevent the ListView from consuming touch input etc
        // Setting ListView's visible property to !model.empty will
        // also work.
        Label {
            visible: model.empty //model.isEmpty() will not work
            horizontalAlignment: HorizontalAlignment.Fill
            verticalAlignment: VerticalAlignment.Center

            text: qsTr("No entries yet\n\nPlease populate data model")
            textStyle.base: SystemDefaults.TextStyles.BigText
            textStyle.textAlign: TextAlign.Center
            multiline: true
        }

    }

    actions: [
        // Action to populate/clear data model depending on state.
        // Same here, model.isEmpty() will not behave as expected.
        ActionItem {
            title: model.empty ? qsTr("Populate") : qsTr("Clear")
            onTriggered: model.empty ? model.populate() : model.clear()
            ActionBar.placement: ActionBarPlacement.OnBar
        }
    ]
}


Screenshots from the example application

A work-around is required because isEmpty() is only an invokable function in QML, and not a bindable property. The example will not behave as expected if model.isEmpty() is set as a value for the Label's visible property. The isEmpty() function is only called once when the Label is created and will never be re-evaluated again since it's not a bindable property (hint to Cascades API developers).

Please feel free to add other ways to accomplish this in the comments section.

Friday, November 23, 2012

More guest posts at devblog.blackberry.com

Forgot to mention that I've posted two more posts at BlackBerry DevBlog a while ago.
The target audience are new comers to QML.

Tuesday, June 26, 2012

Python and Qt on BlackBerry [PlayBook]

I've just bought a BlackBerry PlayBook. After been spending some time with a borrowed PlayBook I decided to buy one myself. Many of you might wonder why the hell I did that but I really think it's a great device. The three top things that made me buy the PlayBook are:
  • Cheap! Good value for the money, the 32 Gb version for only €249
  • Awesome user experience. Really love those swipe gestures which only requires one finger so you can pretty much operate the device with only one finger :). It also gets addictive!
  • It runs Qt and Python!
You might argue that there are very little apps for the PlayBook but admittedly I mostly use the browser so that isn't such a big deal for me. The native PIM-apps integrates well with Google services, such as mail, calendar and contacts. The only thing that I'm missing is an official twitter client. There're a bunch of them on AppWorld but I haven't had time to checked them out yet. RIM do also claim that the PlayBook will be upgradeable to BlackBerry 10 so that should give some confidence of the PlayBook having an upgrade path :)

The PlayBook is powered by QNX which is a real-time micro kernel and supports a lot of POSIX APIs. This basically means that many open source apps/libs for Linux can be ported with little or no effort. What I think is rather cool is that Python 3.2 is pre-installed on the PlayBook which you can use to run Python application.

BlackBerry-Py is a project which goal is to build an environment to support application development in Python for the PlayBook and the upcoming BlackBerry 10 OS. BB-Py uses PySide (Python bindings for Qt) for the UI and the project is also working on support for Cascades. It's very easy to get started so I'll just point you to the "Hello World" example which describes every step you need to take to deploy an app to the device. And no, I didn't find it that hard to get the debug token which you need to install your app on the device :).

Currently the PlayBook OS doesn't include the Qt libraries so they, and PySide, need to be bundled with your app. BB10 is using Qt to a great extent (Cascades is built on top of Qt) and the libraries will be available on the filesystem, only PySide needs to be bundled.

Oh, you also need to download an SDK, for example the Native SDK, to get the required tools for packaging and deploying.

Thursday, June 7, 2012

QML tip over at BlackBerry DevBlog

I've just got a guest post published over at BlackBerry DevBlog.

The post is about adding properties to existing components (Cascades example) to make the code more declarative if you want to track values that are only emitted in signal handlers.

You can read the post here

Thursday, March 8, 2012

Opensourcedays 2012

I've just signed up for opensourcedays 2012 which is held this weekend.

I'm especially looking forward to the talks about Qt and KDE.

Maybe I'll see you there?

Wednesday, October 12, 2011

Open links from Text-elements in QtQuick

I just finished yet another blog post on my companies blog site. It's about opening external application when clicking on links in QML Text-element.

Read about it here

Thursday, September 22, 2011

Using QtCreator for Arduino development

I just finished a blog post on my company's blog site about using QtCreator as development environment for the Arduino board.

Please head over here to read all about it.


Saturday, August 13, 2011

tvmatchen for Nokia N9

I just released a video of my port of tvmatchen for Nokia devices (Symbian^3 and now N9). Tvmatchen is a tv-guide application for live sports and is only available in Swedish.

NokiaGadgets actually wrote a couple of lines about the application, even though the app is in Swedish. The review was very positive and the author wants to see more apps looking like this one. It does feel good in a coders heart when someone writes something positive about your app :)

Link to the article.

And of course the video

Wednesday, June 22, 2011

Nokia N9 and Python

Yet another great day to be a python coder! The new Harmattan/MeeGo device, Nokia N9, will be packed with support for Python!

For more info, look here

Yes, it seems that you can publish your python apps on ovi... Nokia Store too.

Sunday, June 19, 2011

QtQuick - From Bling Bling To Blink Blink

Probably most of you already know that QtQuick is used to create amazing blingalicous UIs without too much effort. The declarative QML language makes it very easy to create object instances and setup property bindings, animation, states etc. Lately I’ve been tinkering with my Velleman K8055 USB experiment board and wanted to create a nice UI to control the board. It didn’t take too long until I was thinking a little bit out side of the box and started experimenting with controlling the board with QtQuick but without a UI. I created a couple of QML components on the C++ side to control the input/outputs of the board and quickly realized the possibilities QML provides even for non-UI applications.

Basically what I did was to create a declarative engine and not a declarative view. By doing this you can have a QML file interpreted and access to the object instances created by the engine from within your C++ code. I see a lot of potential and possibilities, one thing that comes to my mind straight away is to utilize QML as a Dependency Injection container :)
QDeclarativeEngine *engine = new QDeclarativeEngine;
QDeclarativeComponent component(engine, QUrl("qrc:/example1.qml"));
Board *board = qobject_cast<board *>(component.create());
Example code to interpret a QML file
The source code is available at k8055tinker

Check out the video below which demonstrates my code:


I've also tagged this post with Python because it can be of interest for the planet python readers since this can also be accomplished with PySide.

Wednesday, April 20, 2011

I won the "Travelling salesman" competition!

Nokia held a mobile app competition at its Nordic blog which I won!

For more info, look here

Tuesday, March 29, 2011

PySide and QML

It has been out there for a while but I haven't had time to try it out, PySide 1.0 with QML support!

This really gives you a über rapid app development environment. The power of Python combined with the awesomeness of the declarative language QML from the Qt framework.

Take a look and feel free to play with the example below:
from PySide import QtCore
from PySide import QtGui
from PySide import QtDeclarative

class Message(QtDeclarative.QDeclarativeItem):

    messageChanged = QtCore.Signal()

    def __init__(self, parent = None):
        QtDeclarative.QDeclarativeItem.__init__(self, parent)
        self._msg = u''

    def getMessage(self):
        return self._msg

    def setMessage(self, value):
        if self._msg != value:
            print "Setting message property to", value
            self._msg = value
            self.messageChanged.emit()
        else:
            print "Message property already set to", value

    message = QtCore.Property(unicode, getMessage, setMessage, notify=messageChanged)


def main():
    app = QtGui.QApplication([])

    QtDeclarative.qmlRegisterType(Message, "utils", 1, 0, "Message")

    win = QtDeclarative.QDeclarativeView()
    win.setSource("main.qml")
    win.setWindowTitle("Hello World")
    win.setResizeMode(QtDeclarative.QDeclarativeView.SizeRootObjectToView)

    win.show()
    app.exec_()

if __name__ == "__main__":
    main()
import Qt 4.7 // or QtQuick 1.0 if applicable

import utils 1.0

Rectangle {
    id: main

    signal clicked

    color: "black"
    width: 360; height: 360

    Message {
        id: msg

        message: "Click Me!"
        onMessageChanged: label.font.pixelSize = 40
    }

    Text {
        id: label

        anchors.centerIn: parent

        text: msg.message
        color: "white"
        font.pixelSize: 25

 Behavior on font.pixelSize {
            NumberAnimation { duration: 800; easing.type: Easing.OutBounce }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: msg.message = "Hello World"
        }
    }

}
For more information point your browser to http://www.pyside.org and download the package for your OS.

You'll also find useful information at http://developer.qt.nokia.com/wiki/Category:LanguageBindings::PySide

Happy hacking!

Tuesday, February 1, 2011

Guest blog post at Nokia Nordic Blog

I've been invited to write a guest blog post at Nokia Nordic blog. Please check it out if you're interested in Qt-development.

http://blogs.nokia.com/nordicblog/news/meet-mario-the-man-behind-the-qt-app-tvmatchen/#date=2011-02-01,mode=month


Monday, November 29, 2010

Nokia Certified Qt Developer

Now I finally received my Qt certification diploma by mail. Actually, I passed the exam when I attended the Qt DevDays 2010 (october) in Munich. See if I'll go for the advanced exam some day.


Friday, November 12, 2010

Nokia Rules!

There's a conference in the southern part of Sweden (Malmoe) called Oredev which I have been attending this week. I was interested in a talk about MeeGo, meet some Nokia people and to attend a two days Qt course.

Nokia had a booth and I was passing by to check out if they had some Qt stickers which I needed for a demonstration (a simple QML app) I was going to show at my employers booth. To my disappointment they had no stickers but instead I had a great chat with one of guys.

We had an interesting and giving chat about Qt, apps, OviStore, Nokia and MeeGo. Suddenly the guy grabs a package and hands it to me, to my surprise I just realized that he gave me a Nokia N8! He smiled at me and told me to make my app available on OviStore.

Now finally Nokia has given me the opportunity to develop apps for mobile devices since I can use Qt (I already made an app w/o owning a device).

I can't wait for MeeGo devices to show up.

Thanks Nokia!

Saturday, November 6, 2010

Getting Interactive With PyQt

One of the cooler features with PyQt (IMHO) is the possibility to write Qt code interactively. It isn't actually something new and I'm sure it's been there for a while but some of you might not be aware of it. I find it very useful when I want to learn new things in Qt, so without further ado, here's a short introduction on using it.

Start an interactive python session by executing python in a shell:
$> python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
Let's create a simle top-level window (I wont add the '>>>' in case you would like to copy/paste the code):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
app = QApplication([])
window = QWidget()
window.resize(400, 300)
window.show()
Now you should have a window similar to the screen shot below:

Ok, let's create a push button:
button = QPushButton("Click Me!", window)
Hmm, no button shows up... Why? Well, that's because we need to make it visible after we have added it to the window:
button.show()
Ahh, sweet! We have added the button to the window interactively:
Let's put the button at the center of the window by using a layout manager:

layout = QHBoxLayout(window)
layout.addWidget(button)


And finally, let's see how 'layout.addStretch()' affects the layout:
layout.addStretch()

You can easily add a slot to the button's clicked signal:
def mySlot():
    print "Button Clicked"
button.clicked.connect(mySlot)
As you can see, it's an easy way to try out thing in Qt.

Thanks for reading!

Monday, September 27, 2010

Qt DevDays 2010

I'm attending Qt DevDays 2010 and really looking forward to it.

I haven't decided yet which tracks I'll attend, there are so many interesting but I definitely go for some Quick-talks. I believe I'll have a great time.

And that's not all, in November I'll also attend a two day Mobile Qt course at Öredev with topics such as Qt Mobility API, Gesture framework, Hybrid JavaScript apps and last but not least Quick. Looks very promising.

Saturday, September 11, 2010

PyQt and Signal overloads

I almost spent half an hour trying to figure out why my code didn't work.

I used a QSignalMapper to connect a couple of clickable widgets to emit just one signal, widgetClicked(int index), instead of having multiple signals, one for each widget. I connected the widgetClicked signal to the mapped signal of the QSignalMapper class and did the required set up for the signal mapper, something like the following snippet:
self._signalMapper = QSignalMapper(self)
self._signalMapper.mapped.connect(self.widgetClicked)

for index, widget in enumerate(buttons):
    widget.clicked.connect(self._signalMapper.map)
    self._signalMapper.setMapping(widget, index)

Everything worked fine until I changed the signature of widgetClicked to pass a string instead of an int, it didn't work anymore. I only got the following print out: TypeError: connect() failed between 'mapped' and 'widgetClicked' and had no clue why because the mapped signal has a couple of overloads:
void mapped(int i)
void mapped(const QString & text)
void mapped(QWidget * widget)
void mapped(QObject * object)
I did also try changing widgetClicked to not receive any arguments and that worked, which was expected because the receiver is not required to match all arguments of a signal. Of course, it also worked if I changed back to int...

What the #@! is going on? Naturally, I had no option of searching for answers since I was sitting on the train back home from work and had no Internet connection.

Then it come to me, Python is not aware of the C++ signature overload. Python doesn't support overloading. Python/PyQt can't set up the right connection between widgetClicked and mapped. But how do you specify which of the overloads you want to connect to? By indexing:
# This connects your slot/signal to the string-overload
signalMapper.mapped[str].connect(...)
The int overload will be used default by PyQt, that's why my code worked when I connected widgetClicked to mapped w/o specifying which overload I wanted.

Sunday, September 5, 2010

IcecastRadio - Qt widget/Qt Quick example Icecast player

I've been toying with modeling a Qt application which supports both a traditional widget-based view and a quick-based (qml) view.

About IcecastRadio
The intention of this project/application is to demonstrate how important
it can be to design a model for your application. If the model is correctly
designed, it can be used from both traditional widget based UIs and
modern UIs built with Qt Quick without too much effort.

The advantage is of course that you can provide both a desktop application which integrates with the native look and feel of the OS and at the same time have a totally different experience UI-wise, for example in an embedded device by only changing the view-layer.

IcecastRadio is actually two applications, QtCast and QuickCast. QtCast implements the widget-based view and QuickCast the quick-based view. Both application depends on a third entity, the model. You'll see this division in the source code in form of three projects, qtcast, quickcast and model.

The application was successfully compiled against Qt 4.7-beta 1 and 2.

Source code
You'll find the source code at http://gitorious.org/icecastradio. The player code is released under the MIT license, clone and have fun. Please read the README file found in the repository for more information.

Screenshots
Must have...



Remark
The application lacks a lot of features that could be expected from a radio player, for example there is no way of sorting the list of stations nor any filtering can be applied. The intention was not to create a full blown Icecast player but to demonstrate how to create a model that is usable from both a widget-based application and a quick-based application.

Patches are welcome :)