taskMonster2

I get to do a lot of interesting applications at SouthPark. This one in particular was the most challenging use of PyQt that I have experienced to date.

The backstory….
The art department wanted a tool to help them track assigned tasks, the progress, and to share media and notes associated with the tasks. Furthermore, they wanted to be able to skin the interface with custom graphics to make it their own.

Progress…
During the winter break (about a month) I was able to come up with version 1.0 of TaskMonster. It was written in python, using PyQt for the UI, sqlalchemy to talk to the database, and twisted for the client/server communication. Each client app sends messages to a small server daemon which in turn tells the rest of the clients about the updates.

Version 2.0 Alpha…
Tony Postma, from the art department, put together a design in Corel which I could hopefully implement in the UI.  It called for the users to be represented as little pods in a circle around the supervisor, Adrien Beard. And each user pod could be clicked and rotated into place, in order to view that persons tasks.
After a bunch of testing I was able to design a rotating widget that could dynamically lay out N widgets around it in a circle, track their position, and jump to any other widget. I was also able to break down the corel->illustrator file, into a combination of SVG and PNG images, and skin the UI via CSS stylesheets.
Its currently an alpha release. I guess I need to really learn how to control the widget painting, to make it faster. Never had to do this much before.

What I came up with…        Click here to watch the demo video

 

You know when you have all these widgets laid out in your class, and you are hooking up all the connections, and you say “Aw dammit I have to subclass QLabel now just so make it ignore blahEvent”? You end up with all these little widget subclasses, where all they are doing is ignoring an event.

I noticed I was doing this a few times, in more than one of my classes, and finally got annoyed for the last time. I figured there had to be a simple way of just overloading the method on the normal object when I create an instance. Fortunately python considers everything objects and pretty much anything can be changed. So I did this:

myLabel = QLabel()
myLabel.mousePressEvent = lambda event: event.ignore()

Magic.

I have also had to make clickable widgets, such as QLabel:

myLabel = QLabel()
myLabel.mousePressEvent = lambda event: myLabel.emit(SIGNAL("clicked"))

Or if you had to do more than just a single statement:

myLabel = QLabel()
def clickedEvent(event):
    myLabel.emit(SIGNAL("clicked"))
    # do other stuff
        # do stuff
    event.accept()
myLabel.mousePressEvent = clickedEvent

I like this better than piling up subclasses that don’t do much.

 

I had a project where I was designing a statistics reporting site, to track production stats. I wanted to have really nice graphs that pulled from the database and were somewhat live and interactive. XML/SWF Charts is this awesome flash-based app that lets you embed graphs in your pages which receive their data from XML. There are tons of graph types and ways to customize the look.

http://www.maani.us/xml_charts/index.php

So, the thing is… I wanted to use Django for the site. I decided to write a python module that wraps around the API for SWF charts, so that the XML could easily be generated for me after just setting all my parameters. Thought I might post this here for any python fans wanting nice looking graphs in their site.

Really, this doesn’t just apply to django. You could just call out from anything to python code that will generate your XML for you.

Example:

chart = SwfChart()

# the data
chart.addRow( 'Person A', 1, 10, 5.5 )
chart.addRow( 'Person B', 6, 4.45, 8 )
chart.addColumnLabel( 'Day1', 'Day2', 'Day3' )

# Extra graph settings
chart.addFilter('shadow', 'low', distance=2, angle=45, alpha=35, blurX=5, blurY=5)
chart.addFilter('shadow', 'high', distance=3, angle=45, alpha=35, blurX=10, blurY=10)
chart.addFilter('bevel', 'bevel1', strength=10, quality=3, distance=2)
chart.setChartBorder(top=1, bottom=2, left=0, right=0, color='000000')
chart.setChartLabel(color='000000', alpha=80, size=8, position='outside', hide_zero=True)
chart.setChartTransition(type='scale', delay=.5, duration=.5, order='series')
chart.setChartRect(shadow='high')
chart.setLegend(size=12, alpha=90, fill_alpha=30)
chart.setAxisTicks(category_ticks=True, value_ticks=True, minor_count=3)
chart.setContextMenu(about=False)

# if you have the licensed version
chart.setLicense('license string')

Now at this point, the object can be treated like a string to get the xml, or just call getXML() :

print chart

print chart.getXML()   # same thing

xml = str(chart)   # or assign the XML string somewhere

You can download the swfcharts.py module and use it freely. If you find it helpful, post a comment or shoot me an email.

Download swfcharts.py

Pydoc located here for convenience:
swfcharts python documentation

© 2011 Justin Israel | justinfx.comSuffusion theme by Sayontan Sinha