PyQt — Part 2

3 08 2009

I’ve been a little busy the last few weeks and haven’t really had much time to write a good post. I promise more next week. This week I’m using an example that I used in my lightning talk at PyOhio. It’s pretty simple and straight forward, it just gives you more of an idea of how to use PyQt in an organized manor.

PyQt-Part2.py (Download):

#!/usr/bin/python
 
import sys
from PyQt4 import QtGui, QtCore
 
class LanguageSelectorWidget(QtGui.QWidget):
  def __init__(self, parent=None):
    QtGui.QWidget.__init__(self, parent)
    self.setGeometry(300, 300, 250, 150)
    self.setWindowTitle('LanguageSelector')
 
    comboBox = QtGui.QComboBox(self)
    comboBox.addItem('Python')
    comboBox.addItem('Java')
    comboBox.addItem('Ruby')
 
    self.textEdit = QtGui.QTextEdit(self)
 
    okButton = QtGui.QPushButton('Ok', self)
    cancelButton = QtGui.QPushButton('Cancel', self)
 
    buttonLayout = QtGui.QHBoxLayout()
    buttonLayout.addWidget(okButton)
    buttonLayout.addWidget(cancelButton)
 
    mainlayout = QtGui.QVBoxLayout(self)
    mainlayout.addWidget(comboBox)
    mainlayout.addWidget(self.textEdit)
    mainlayout.addLayout(buttonLayout)
 
    self.connect(comboBox, QtCore.SIGNAL('currentIndexChanged(int)'), self.comboxBoxUpdated)
    self.connect(okButton, QtCore.SIGNAL('clicked()'), QtGui.qApp, QtCore.SLOT('quit()'))
    self.connect(cancelButton, QtCore.SIGNAL('clicked()'), QtGui.qApp, QtCore.SLOT('quit()'))
 
    comboBox.setCurrentIndex(1)
 
  def __del__(self):
    print self.textEdit.toPlainText()
 
  def comboxBoxUpdated(self, index):
    if index == 0:
      self.textEdit.setText('Snakes are scary!')
    elif index == 1:
      self.textEdit.setText('Coffee is hot!')
    else:
      self.textEdit.setText('Diamonds are forever!')
 
# Run application
if __name__ == "__main__":
  app = QtGui.QApplication(sys.argv)
  qb = LanguageSelectorWidget()
  qb.show()
 
  sys.exit(app.exec_())

Here is a preview of what the above code will generate (XFCE4 in Linux):

Screenshot

In the above example my class “LanguageSelectorWidget” inherits from “QWidget” (a base widget class). Doing this allows me to easily contain all of the other widgets inside my class and easily manage their communication. This example would make a great dialog for a larger application. You can see in the destructor the final value in the text box is printed to the command-line. This could also be returned to the invoking object, written to a database, used to invoke another program, etc.



Qt Threading with Mutex

20 07 2009

In my previous example of threading with Qt I gave a quick run down of communicating between a GUI thread and a worker thread. This tutorial is a little different in that I will be using six worker threads and no GUI threads.

In this tutorial I will primarily be focusing on the use of mutex (using QMutex to demo). First off, a mutex (short for mutually exclusive) is a locking mechanism used in multi-threaded programs that prevents other threads from entering a specific section of code, commonly known as a “critical section”. One example of a critical section is making database transactions, another similar example would be adding and removing items from a list. The reason these are labeled as “critical sections” is because they are munipulating the same object in different threads. Why is that so bad? Because it is possible that you will delete an item from the list in thread0 while that very item is being read in thread1. This of course will likely cause a crash.

In the following example I simulate multiple threads accessing a single database object. Below you see the results with a mutex and without.

DatabaseObject.h (Download):

/* Filename: DatabaseObject.h */
#ifndef DATABASEOBJECT_H
#define DATABASEOBJECT_H
 
#include <QDebug>
#include <QTime>
#include <QThread>
#include <QMutex>
 
class DatabaseObject : public QObject
{ 
public:
   DatabaseObject(bool useLocking = true) 
   {
      m_UseLocking = useLocking; 
      QTime midnight(0,0,0);
      m_Seed = midnight.msecsTo(QTime::currentTime()); 
   }
 
   void AddToDb()
   {
      if(m_UseLocking) m_Mutex.lock();
      qDebug() << "Add Started";
      simulateDbOperation(); // Simulate db operation
      qDebug() << "Add Finished";
      if(m_UseLocking) m_Mutex.unlock();
   }
 
   void RemoveFromDb()
   {
      if(m_UseLocking) m_Mutex.lock();
      qDebug() << "Remove Started";
      simulateDbOperation(); // Simulate db operation
      qDebug() << "Remove Finished";
      if(m_UseLocking) m_Mutex.unlock();
   }	
 
protected:
   void simulateDbOperation()
   { 	
      m_Seed++; /* qsrand is thread safe, we need to offset it */
      qsrand(m_Seed);
      QTime dieTime = QTime::currentTime().addMSecs(qrand() % 700);
      while(QTime::currentTime() < dieTime);
   }
 
private:
   int m_Seed;
   QMutex m_Mutex;
   bool m_UseLocking;
};
#endif

WorkerThread.h (Download):

/* Filename: WorkerThread.h */
#include <QThread>
 
#include "DatabaseObject.h"
 
class WorkerThread : public QThread
{
public:
   WorkerThread() { m_dbObject = NULL; }
   ~WorkerThread() { }
   void setDbObject(DatabaseObject *dbObject) { m_dbObject = dbObject; }
 
protected:
   // This is the entry point for the thread.
   virtual void run()
   {
      m_dbObject->AddToDb();
      m_dbObject->RemoveFromDb();
   }
 
private:
   DatabaseObject *m_dbObject;
};

main.cpp (Download):

/* Filename: main.cpp */
#include "WorkerThread.h"
#include "DatabaseObject.h"  
 
#define NUMOFTHREADS 6
 
int main(int argc, char **argv)
{
   DatabaseObject dbObj(true); /* Use false to disable mutex */
   WorkerThread threads[NUMOFTHREADS]; 
 
   // Set Id's
   for(int i = 0; i < NUMOFTHREADS; i++)
      threads[i].setDbObject(&dbObj);
 
   // Start the work
   for(int i = 0; i < NUMOFTHREADS; i++)
      threads[i].start();
 
   // Wait for the thread to finish
   for(int i = 0; i < NUMOFTHREADS; i++)
      threads[i].wait();
 
   // Return
   return 0;
}

Results:

## With QMutex ##                    ## Without QMutex ##
   Add Started                          Add Started
   Add Finished                         Add Started 
   Add Started                          Add Started 
   Add Finished                         Add Started 
   Remove Started                       Add Started
   Remove Finished                      Add Started 
   Add Started                          Add Finished
   Add Finished                         Remove Started
   Add Started                          Add Finished
   Add Finished                         Remove Started
   Add Started                          Add Finished
   Add Finished                         Remove Started
   Remove Started                       Remove Finished
   Remove Finished                      Add Finished 
   Add Started                          Remove Started
   Add Finished                         Add Finished
   Remove Started                       Remove Started
   Remove Finished                      Add Finished
   Remove Started                       Remove Started
   Remove Finished                      Remove Finished
   Remove Started                       Remove Finished
   Remove Finished                      Remove Finished
   Remove Started                       Remove Finished
   Remove Finished                      Remove Finished

You’ll notice that when using QMutex once a critical state is entered (IE AddToDb or RemoveFromDb) no other thread can enter a critical state until it is finished. Adding and removing may happen out of order, thats okay, what we care about is once an add or removed is started it most be followed by a corresponding “finished”. When not using a mutex threads you can see that threads enter a critical state before other finish.

In the above example we are running 6 different threads at once. When QMutex is locked and another thread calls QMutex.lock() it will block until it is it’s turn. If you would like to learn more about threading with the Qt Framework I recommend this as a start Thread Support in Qt.

For those of you who are not very familar with Qt you can build this example rather quickly.

  1. Create a new directory and save the above three files in it.
  2. Enter that directory at the command line (Bash, DOS, etc).
  3. Type ‘qmake -project’.
  4. Type ‘qmake’.
  5. Type ‘make’ (or ‘nmake’ if using Visual Studio in Windows).


Inheritance, Polymorphism and Virtual Methods

11 07 2009

In object-orientated programming inheritance, also known as subclassing, is creating a new class that has methods from a parent class. When you create a new class that inherits from another class it copies the public and protected methods from the parent class. The technique is widely used and has many benefits. It reduces code bloat, makes maintenance easier, quicker implementation, just to name a few.

Here is an example of inheritance in Java:

/* Person.java */
public class Person {
   private String m_name;
 
   public String GetName() { return m_name; }
   public Person(String name) { m_name = name; }
}
 
/* Student.java */
public class Student extends Person {
   private String m_studentId;
 
   public String GetStudentId() { return m_studentId; }
   public Student(String name, String studentId) { 
      super(name);    /* Invoke parent constructor */
      m_studentId = studentId;
   }
}
 
/* Example.java */
public class Example {
   public static void main() {
      Student s = new Student("Wesley", "u001");
 
      System.out.println("Name: " + s.GetName());
      System.out.println("StudentId: " + s.GetStudentId());
   }
}

As you can see the “GetName()” method is implemented in the “Person” class and because the “Student” class is a sub-class, it gets access to the method without having to declare it. This is one of the major benefits of inheritance.


Now that you’ve seen the basics of inheritance it’s time to discuss polymorphism. Polymorphism is a feature of object-oriented programming that allows a subclass to be safely type casted to it’s parent class.

/* Using Person.java and Student.java from the previous example */
 
/* Example.java */
public class Example {
   public static void DisplayName(Person p) {
      System.out.println("Name: " + p.GetName());
   }
 
   public static void main() {
      Student s = new Student("Wesley", "u001");
 
      DisplayName(s);
   }
}

In the above example you can see that the method “DisplayName” takes objects of type Person, however because Student is a subclass of Person it can be safely type casted to Person.

In this example the use of polymorphism is a bit trival, but the real benefit comes when working with a framework. For example in the Qt Framework there is a common widget called QWidget. If I choose to subclass QWidget and add some additional functionality to it, I still want to use it with other functions that take an object of type QWidget. Polymorphism makes it possible for my subclass widget to interact with the Qt Framework as a QWidget.


A virtual method is a feature that really breathes life into polymorphism. Virtual methods are methods that are declared in a parent class, (re)defined in a child class and invoked on an object that is of type parent class (wow, did you get all of that?). This can be easily illustrated by an example.

/* Animal.java */
public class Animal {
   public String GetDisplayName() { return "I am an animal."; }
}
 
/* Dog.java */
public class Dog extends Animal {
   public String GetDisplayName() { return "I am a dog."; }
}
 
/* Example.java */
public class Example {
   public static void DisplayAnimal(Animal a) {
      System.out.println(a.GetDisplayName());
   }
 
   public static void main() {
      Animal a = new Animal();
      Dog d = new Dog();
 
      DisplayAnimal(a);
      DisplayAnimal(d);
   }
}

Output:

I am an animal.
I am a dog.

In this example the DisplayAnimal method takes an object of type animal and invokes “GetDisplayName”. Even though the object “d” is typecasted to it’s parent class, the definition of “GetDisplayName” which is redefined in the child class is held after the typecast. This is what really makes the whole idea of polymorphism so glamorise, the fact that you can create a custom subclass with additional and/or different functionality and it can still interact with other methods that expect it’s parent type.

This blog uses Java to display inheritance, polymorphism and virtual methods, however almost all object-oriented langauges have this ability (C++, C# and Python, just to name a few).



Qt Threading and Communication

6 07 2009

The Qt Framework makes threading in C++ a bit easier. In general it is cross-platform, it can be easier to implement and communication between threads. In the following example we calculate prime numbers in a “worker thread” and we display the results in a gui dialog which is drawn through the event thread.

For those of you not familar with GUI programming it is important to do time consuming stuff (IE number crunching, network activity, etc) in a seperate thread. The reason for this is that even if your program is just sitting there waiting, it’s event loop is constantly repainting the window and responding to user driven events (keyboard, mouse, etc). If you tie the event loop up for too much time your application will appear frozen to the user, hence the importance of threading.

In the example below we create an instance of the WorkerThread (see main.cpp). We use signals and slots to communicate between the worker thread and the event loop. Once we invoke thread.start() a thread is created and it begins by calling the protected function run().

WorkerThread.h:

/* Filename: WorkerThread.h */
#include <QThread>
#include <QString>
 
class WorkerThread : public QThread
{
	Q_OBJECT
 
public:
	WorkerThread(QObject* parent = 0) : QThread(parent) { }
	~WorkerThread() { }
 
signals:
	void signalStatusUpdate(QString);
 
protected:
	// This is the entry point for the thread.
	virtual void run()
	{
		for(uint i = 1; i < 1000; i+=2)
		{
			bool isPrime = true;
 
			for(uint j = 3; j < i; j+=2) 
			{
				if(i % j == 0)
				{
					isPrime = false;
					break;
				}
			}
 
			if(isPrime)
			{
				emit(signalStatusUpdate(QString("%1").arg(i)));
				msleep(100);
			}
		}
 
		emit(signalStatusUpdate("Done."));
	}
};

main.cpp:

/* Filename: main.cpp */
#include <QApplication>
#include <QPlainTextEdit>
#include <QSlider>
 
#include "WorkerThread.h"
 
 
int main(int argc, char **argv)
{
	QApplication app(argc, argv);
	QPlainTextEdit textFrame;
	WorkerThread thread;
 
	// Connect the threads signal to the textFrame's slot
	QObject::connect(&thread, SIGNAL(signalStatusUpdate(QString)), &textFrame, SLOT(appendPlainText(QString)));
 
	// Show the text frame
	textFrame.show();
 
	// Start the work
	thread.start();
 
	// Turn over control the event loop
	return app.exec();
}

For those of you who are not very familar with Qt you can build this example rather quickly.

  1. Create a new directory and save both files in it.
  2. Enter that directory at the command line (Bash, DOS, etc).
  3. Type ‘qmake -project’.
  4. Type ‘qmake’.
  5. Type ‘make’ (or ‘nmake’ if using Visual Studio in Windows).


PyQt

5 07 2009

I’m a pretty big fan of the Qt Framework, I use it at work and at home for my personal apps. In a few weeks I’ll be attending a two day python conference so I thought I’d brush up on some python. What better way than to mess with the Qt Bindings for python.

Here is a simply hello python. More to come:

#!/usr/bin/python
 
import sys
from PyQt4 import QtGui
 
app = QtGui.QApplication(sys.argv)
 
widget = QtGui.QWidget()
widget.resize(250, 150)
widget.setWindowTitle('Hello Python')
widget.show()
 
sys.exit(app.exec_())


Javascript and Flex Communication

11 04 2008

A couple days a go I was writing a quick flex app at work and it became necessary for me to be able communicate between javascript and flex, that is, making javascript calls from flex and making flex calls from javascript. After a bit of research, I found that it is a pretty easy thing to do. To make it easier to see what is going on I’m splitting this up into two separate examples.

Making javascript calls from flex:

<?xml version="1.0" encoding="iso-8859-1"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="300" height="86" layout="absolute"  >
    <mx:Script>
    	<![CDATA[
        	import flash.external.*;
 
    		function buttonClicked():void {
    			ExternalInterface.call("alert", userInputField.text);
    		}
		]]>
    </mx:Script>
 
	<mx:TextInput id="userInputField" x="20" y="28"  width="191"/>
	<mx:Button label="JS Alert" click="buttonClicked()"  x="219" y="28"/>
</mx:Application>

Get FlashPlayer

The above example makes a simple call to the javascript function “alert” and passes the text in the text field as an argument to the alert function. To pass more than one argument simply just add them as additional arguments to the ExternalInterface.call() method. Example: ExternalInterface.call(”myJsFunction”, “arg1″, “arg2″);


Making flex calls from javascript:

<?xml version="1.0" encoding="iso-8859-1"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="300" height="86" layout="absolute" creationComplete="init()" >
    <mx:Script>
    	<![CDATA[
        	import flash.external.*;
 
    		function init():void {
    			ExternalInterface.addCallback("setTextField", setTextField);
    		}
 
    		function setTextField(userInput:String):void {
    			userInputField.text = userInput;
    		}
		]]>
    </mx:Script>
 
	<mx:TextInput id="userInputField" x="20" y="28"  width="191"/>
</mx:Application>
var flexApp;
 
if (navigator.userAgent.indexOf("MSIE") != -1) {
	flexApp = window[flexElementObjectId];
} else {
	flexApp = document[flexElementObjectId];
}
 
flexApp.setTextField("Hello World");

This example invokes a flex function from javascript. As you may have noticed this is relatively simple, all you need to do is add a an external callback within flex and make a call to the DOM object from Javascript.



Upload XML into Flex

10 01 2008

Today I was asked to add some functionality to a flex application I have been developing, that functionality was to give users the option to upload the XML data file, rather than fetch it from the server. I won’t go in to the details of the application, just that it is completely driven on its data, which is provided via XML. After doing some reading I was surprised to learn that it is not possible to upload an XML file without a server side script of some kind. I choose to use PHP because its quick, easy, and simple. So the concept is that the user sends the file through flex to a server side script, that script accepts the file and returns its contents back to flex as XML.

Here is the flex code:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
  layout="absolute" width="275" height="354" 
  creationComplete="init()">
<mx:Script>
<![CDATA[
  import mx.rpc.events.*;
  import flash.events.*;
  import flash.net.FileReference;
  import flash.net.URLRequest;
  import flash.net.FileFilter;
 
  private var myXML:XML;
  private var file:FileReference;
 
  private function init():void {
    file = new FileReference();
 
    // Add Event Listners
    file.addEventListener(Event.SELECT, userSelectedFile);
    file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, serverResponse);
  }
 
  private function browse():void {
    file.browse([new FileFilter("XML", "*.XML;")]);
  }
 
  // Called after the user selects the file to upload
  private function userSelectedFile(event:Event):void {
    file = FileReference(event.target);
    file.upload(new URLRequest("file_upload.php"), "FileData", false);
  }
 
  // Called after flex receives response from PHP
  private function serverResponse(event:DataEvent):void {
    myXML = XML( event.data );
    XML_Box.data = myXML;
  }
]]>
</mx:Script>
<mx:VBox>
</mx:VBox>
  <mx:Button id="Upload" label="Upload" click="browse()" x="200" y="322"/>
  <mx:TextArea id="XML_Box" width="250" height="300" x="12.5" y="10"/>
</mx:Application>

Here is the php code:

<?php
// Set the header information
header ("content-type: text/xml");
 
// Open the uploaded file
$file_handler = fopen($_FILES["FileData"]["tmp_name"], "r");
 
// Display the file contents
while(!feof($file_handler))
{
        echo fgets($file_handler);
}
 
// Close the file
fclose($file_handler);
?>

That’s all there is to it! To try it out just click the upload button and select an XML file to upload. If you don’t have an XML file handy you can use this sample file.
Get FlashPlayer



The power of recursion

5 01 2008

Recursion can be a powerful technique for any programmer, but it’s important to understand its application, when it should be used and when it should not be.The whole idea behind recursion is to have a function or method which calls itself, this has the effect of breaking down the data in sub portions so that it can be handled easier. One of the most common applications for recursion is used injunction with tree data structures. In a tree data structure each node contains data and any number of sub nodes or children which may also contain data and any number of children.Here is a very common example of recursion in which we calculate the Fibonacci Number.

int fibonacci( int n )
{
  if( n == 0 )
    return 0;
  if( n == 1 )
    return 1;
  if( n > 1 )
    return fibonacci(n-1) + fibonacci(n-2);
}

Now you have a very small function, but powerful function that can easily and accurately compute a Fibonacci number. This is just one of the many useful applications of a recursive function. If I have peaked your interest I recommend that you continue reading about recursion, the wikipedia recursion article is a good start.



Hello world!

21 12 2007
<script type="text/javascript">
  alert('Hello World!');
</script>
<?php
  echo "Hello World!";
?>
public class HelloWorld {
  public static void main(String[] args) {
    System.out.println("Hello World!");
  }
}
#include <iostream>
 
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}

You get the idea.