Harsh J

Memoirs of a QWERTY Keyboard

Archive for the ‘Software’ Category

Pomodoro and KDE

2 comments

Am no follower of the Pomodoro technique nor do I know its specifics but before you go ahead and try out those multiple Adobe AIR applications or use the GNOME-oriented Workrave, please try out this software called RSIBreak which was built for KDE specifically.

RSIBreak - Repetitive Strain Injury prevention software for KDE

RSIBreak - Repetitive Strain Injury prevention software for KDE


It isn’t a full fledged timer feature but I think it will get your needs covered with its offerings easily enough. One of the amazing utilities I’ve used, built with KDE Libraries. It should be available in your Linux distribution’s software repository too.

Written by Harsh

May 5th, 2010 at 3:22 pm

PyQt – Creating interfaces visually with Designer

2 comments

Note: If you’re new to using PyQt but are interested in great cross-platform GUI application development please read the PyQt Introduction article.

Designing a graphical interface for an application could be a tiresome task. There are guidelines to keep track of, layouts to maintain and more of such stuff. In the PyQt code samples you’ve seen so far we’ve written our interfaces in pure code. While this is fun and easy to do for little applications that consist of about 5 to 10 widgets, it’s not worth spending the time upon in creating fully blown up interfaces for complete applications.

The Qt Designer

Fortunately, Qt provides us a tool to design interfaces and to port it to usable code automatically. This tool is called the Qt Designer, and it comes with the Qt library bundle you installed. Additionally we would require a converter for processing the XML .ui files Designer produces into a python module .py file; also installed with the PyQt4 bundle.

Thus, to design in PyQt we need the two following tools:

  • Qt Designer from Nokia’s Qt Software
  • The pyuic4 script from Riverbank’s PyQt

Once you have Designer and PyQt4 tools installed, let’s fire it up and get started.

The initial interface might look familiar to those who have used Visual Studio, or Glade and such tools. For the rest, it’s intuitive enough to learn smoothly. Read the Qt Designer guide for more elaborate help if you still don’t find it usable.

The Qt Designer

The Qt Designer

In this article, we’ll be using Designer to design and create a simple Image Viewer application.

References: Qt Designer, The PyQt + Qt Designer Documentation

Image Viewer

Our Image Viewer application would be a very simple one, with options to Open an image file of major types (JPEG, PNG, GIF, etc.) and another to Quit. Upon opening of an image, we shall also set the status bar to show the dimensions of the image.

Designing the GUI

Open Qt Designer (‘designer’ command if on Linux) and choose File | New | “Main Window” under templates/forms expansion. This creates a new QMainWindow widget for us to work upon. The QMainWindow is basically a composition of a main-area widget, a menu-bar and a status-bar at the bottom, the very usual stuff an application consists of.

Design of the Image Viewer UI

Design of the Image Viewer UI

From the Widget Box, drag a Label onto the main window’s area. Right-Click at any of the free space available on the same area, choose the “Lay out” sub-menu and then hit the “Lay out Horizontally” option. Designer will automatically stretch your Label across the area available this way. We need this layout (any layout will do here, actually) since we want the image to show in the entire window area.

Now on to menus, Add a File menu and under it add an Open and a Quit option, as shown below. To add these just click where it says “Type here” and get typing; Hit Enter/Return key to get to the next element in the menu after you’ve typed.

Under the Property Editor, select and set the Label’s text property to blank, and its alignment property to AlignHCenter and AlignVCenter. This completes our UI design in Qt Designer. But don’t quit already, do explore the other properties of the widgets used and figure out their possible uses; get used to the interface and available tools like Form Previews, etc.

The imageLabel (QLabel) object Properties

The imageLabel (QLabel) object Properties

For instance, check out the properties like geometry (Height and Width), font, tooltip, etc. If you’re in a good reading mood, also checkout the amazing Style Sheet documentation in Qt Assistant, as it explains a lot about each Widget’s construct and how to go about customizing it till your heart’s content.

Finally, renaming the widget elements’ variables would be a good idea, since it will help us code our application in a much more readable manner. This is how I’ve named these widgets but feel free to follow whatever naming conventions you would like to use:

Image Viewer object names

Image Viewer object names

Just double-click on the Object Name items and edit them in-line after that. Note and remember your QMainWindow class’s object name. Once you’re done, save the file as ‘ImageViewerUI.ui‘.

References: QLabel, QAction, QMenuBar, Layouts Guide

Using PyQt’s pyuic4 script

Our next step requires the use of the aforementioned pyuic4 tool. It’s usage syntax is as follows:

pyuic4 input_file.ui -o output_file.py
# Optionally takes -x parameter to make the generated code executable.

Thus we should run, for our UI file:

pyuic4 ImageViewerUI.ui -o ImageViewerUI.py

This will create a file ImageViewerUI.py that we can now use. Looking into the file will show you that its just a long list of widget constructs and of applying property settings. There is no need to edit this file, and is advised not to since pyuic4 will over-write all changes in it if you run it once again after some changes you wanted to do.

Whenever you edit your .ui files, make sure to run the pyuic4 tool to convert it into its Python equivalent (or to update existing Python code such that it reflects the new changes).

Additional info: Try `pyuic4 –help` for more fine-tuning options.

Running the basic GUI

Create a new file ImageViewer.py to finally add the application logic. Before we get to the code part, let me explain how the Qt’s subclass approach works. A Qt Designer file is inherited by the QMainWindow-derived class, and then the interface is setup using the setupUi() call with an instance. This creates all the objects/widgets for the interface as attributes of the derived QMainWindow class so that it’s ready to show. Next, we need to add the application-level logic to this derived class as normal methods. Since we have access to all the widgets used in the interface via our class, we can do as we like with their available features. The following diagram explains the hierarchy we ought to follow each time we need to implement a UI class for use:

Image Viewer Inheritance Diagram

Image Viewer Inheritance Diagram

Thus, a basic class that can be run would look like:

#!/usr/bin/python

from PyQt4 import QtGui, QtCore
import sys

# Import the interface class
import ImageViewerUI

class ImageViewer(QtGui.QMainWindow, ImageViewerUI.Ui_mainWindow):
    """ The second parent must be 'Ui_<obj. name of main widget class>'.
        If confusing, simply open up ImageViewer.py and get the class
        name used. I'd named mine as mainWindow, hence Ui_mainWindow. """

    def __init__(self, parent=None):
        super(ImageViewer, self).__init__(parent)
        # This is because Python does not automatically
        # call the parent's constructor.
        self.setupUi(self)
        # Pass this "self" for building widgets and
        # keeping a reference.

    def main(self):
        self.show()

if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    imageViewer = ImageViewer()
    imageViewer.main()
    app.exec_()
    # This shows the interface we just created. No logic has been added, yet.

Run this class and you can see the window you just created.

Basic GUI of Image Viewer during Runtime

Basic GUI of Image Viewer during Runtime

You MUST call self.setupUi(self) to make the UI file run the setup statements and build the GUI interface for use by our class.

References: QMainWindow

Adding Application Logic and other Code

Now to add the opening-an-image feature, let’s define a few methods in the class as:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtGui, QtCore
import sys

# Import the interface class
import ImageViewerUI

class ImageViewer(QtGui.QMainWindow, ImageViewerUI.Ui_mainWindow):
    """ The second parent must be Ui_<obj. name of main widget class>. \
      If confusing, simply open up ImageViewer.py and get the class \
      name used. I'd named mine as mainWindow and hence the use. """

    def __init__(self, parent=None):
        super(ImageViewer, self).__init__(parent)
        # This is because Python does not automatically
        # call the parent's constructor.
        self.setupUi(self)
        # Pass this "self" for building widgets and
        # keeping a reference.
        self.connectActions()

    def connectActions(self):
        self.actionQuit.triggered.connect(QtGui.qApp.quit)
        # Connect the Quit action's triggered signal
        # to a proper Quit method
        # given by qApp (which points to your QApplication
        # object).
        self.actionOpen.triggered.connect(self.openImage)
        # Connect the Open action's triggered signal
        # to load an image onto the image label.

    def openImage(self):
        # Lets get a user-provided file to open
        # using PyQt's QFileDialog class.
        fileName = QtGui.QFileDialog.getOpenFileName(
                        self,
                        "Open Image File",
                        QtCore.QDir.homePath(),
                        "Image Files (*.jpg *.jpeg *.gif *.png)"
                    )
        # Don't attempt to open if open dialog
        # was cancelled away.
        if fileName:
            self.imageLabel.setPixmap(QtGui.QPixmap(fileName))
            # Load the image file as a pixmap onto the
            # labelImage QLabel GUI object.

    def main(self):
        self.show()

if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)
    imageViewer = ImageViewer()
    imageViewer.main()
    app.exec_()

Note the two new method additions connectActions() and openImage(). They complete the application logic that’s involved for our image viewing application example. Try to understand them better by seeing the PyQt classes used in them and referring them up in Qt Assistant for much more detailed information.

Now the application can open images via File | Open and can also be quit via File | Quit.

This is the final result of our work:

Image Viewer in Action

Image Viewer in Action

References: QPixmap, QFileDialog, qApp

Exercise

Try to build a simple text-based evaluator application that contains of two things:

  • A text input box that allows for mathematical expressions input.
  • An output label or text area (non-editable) for showing results of these expressions.

Classes you could use are QLabel, QLineEdit and QTextEdit. Another hint is to use Python’s ‘eval‘ function. As a bonus try to make the evaluation via Python safe.

Written by Harsh

April 18th, 2010 at 9:28 pm

KDE and the .gtkrc

leave a comment

In my quest to have a perfectly usable dark theme I found I would require two things:


Having acquired those, I went on to install and select them via System Settings’s Appearance applet and all my Qt4+KDE4 applications looked neat in their dark avatars. Next I had to make Chromium reflect and respect the native theme settings and found an option for it to “Use GTK Theme” under Settings – Options – Personal Stuff.

However upon switching that on I realized that GTK themes were indeed showing the coloring of darkPearl right but not the widget styling that the darkPearl + QtCurve provide together, despite placing a proper QtCurve .gtkrc and its other known aliases at all key positions. Sometimes it’d work after doing the last action, but only for the current KDE session and it would all go back to simple-coloring hell post a re-logon.

The solution to this was apparently under System Settings’s Appearance – Colors applet itself. I’d missed an option under the Options tab of Colors that said “Apply color to non-KDE4 Applications“. Un-check this and the custom .gtkrc you place sticks like its supposed to. Chromium looks great now! So does GIMP, the second of the two GTK-using applications I use.

Written by Harsh

April 17th, 2010 at 4:41 pm

UML Blues

2 comments

Turn those blues to violet using Violet ;)

Violet was the UML modelling tool I had to use to save me some fun-later-time and make the whole process quick and painless. It also supports exporting to an image format and all in all it is a lovable, simple and just-works tool. But do note that it uses Java to do all that magic.

The other alternative I had was Umbrello which sadly isn’t in a very usable state yet. Perhaps this summer its GSoC fix may make it better. Wish I knew enough of QGraphicsView stuff to try it myself :)

Written by Harsh

March 29th, 2010 at 10:34 pm

Using the BSNL 3G Data Card on Linux

25 comments

This article shall detail the steps to setup, configure and begin using the Huawei E156 HSDPA (3G) USB Stick on Linux (fondly called by them BSNL employees as a ‘Data Card’).

On Windows, one generally uses the bundled ‘Huawei Mobile Partner’ software which does wonderful things like read messages, compute statistics, etc. There isn’t a similar software on Linux providing all of those under one roof, however.

First off, you need to create a BSNL 3G dialer profile, and you would require a software known as wvdial. Install it by either of these commands, in the Terminal application:

# On Ubuntu
sudo aptitude install wvdial

# On ArchLinux
sudo pacman -S wvdial

Now as root (or using sudo), open the file: /etc/wvdial.conf

# If you use GNOME, try:
sudo gedit /etc/wvdial.conf

# If on KDE, try:
sudo kwrite /etc/wvdial.conf

Paste into your editor, the following lines:

[Dialer bsnlnet]
Modem Type = Analog Modem
Phone = *99#
ISDN = 0
Baud = 460800
Username = " "
Password = " "
Modem = /dev/ttyUSB0
Init1 = ATZ
Init2 = at+cgdcont=1,"ip","bsnlnet"
Stupid Mode = 1

Save the changes and close the editor. Now to get connected, you have to ask the wvdial command to start a particular connection. So simply do, on each startup:

wvdial bsnlnet

And lo, you’re online with blazing 3G speeds!

Note: You may be supposed to use a different APN like bsnlsouth sometimes (instead of bsnlnet or etc.), so change that in the highlighted line.

Written by Harsh

March 22nd, 2010 at 9:49 am