maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Development (https://talk.maemo.org/forumdisplay.php?f=13)
-   -   Build a simple Fart App in 30 Mins! N900, PyQt (https://talk.maemo.org/showthread.php?t=54380)

kojacker 2010-05-29 01:50

Build a simple Fart App in 30 Mins! N900, PyQt
 
1 Attachment(s)
The finished app, a list of fart sounds to choose from on the left and a big dangerous red push button on the right..

http://i90.photobucket.com/albums/k2...528-230425.png

This is a beginner tutorial in association with the N900 coding competition , running til July 21st. Please get involved :)

This tutorial covers:

• GUI creation with Qt Designer
• Sound playback with phonon
• Getting around the lack of a switch/case statement in python
• The mystical art of naming fart sounds

Pre-requisites:

If you are a beginner please go through the starter tutorials from MikeC and FatalSaint first, which are both many times more informative and better thought out than this one and will also help get your environments set up.

• MikeC - http://talk.maemo.org/showthread.php?t=43663
• FatalSaint - http://talk.maemo.org/showpost.php?p...8&postcount=59
• Python and PyQt should be installed correctly on your PC and n900
• You should have WinSCP on your PC and OpenSSH client-server on your n900 (or equivalents) for copying the files over.

Caveats

I am also a beginner, this tutorial is put out there in the hope it helps but should not be seen as well written or particularly ‘good’.


Step 1:
Go and grab yourself 5 or 6 fart sounds from the internet. A simple google search should find plenty of .wav farting audible goodness, e.g. http://www.fartgreetings.com/fartwavs.asp might be a start. Or you can use the ones I have attached in the zip file.

Step 2:
Fire up your copy of Qt Designer, from the first dialog choose the Main Window template and set the canvas size to 800*400. We only need two widgets - a List Widget, which is used to select the fart sound, and a Push Button widget to trigger the sound to be played. Drag both widgets onto the canvas, with the list to the left and the button to the right. Space them out and resize them until you’re happy with how they look. For more info on using a layout and use of spacings see FatalSaint’s tutorial linked at the beginning.

http://i90.photobucket.com/albums/k2...ithwidgets.png

Step 3:
Left click on the List Widget, and in the Property Editor change it’s name to ‘soundList’. Then right click on the List Widget and choose “Edit Items” from the mouse’s popup menu. A small window called the “Edit List Widget” will appear, and this is where you enter the fart names that the user will see and click on. Click on the green + symbol on the bottom left corner of the widget and add a name for each of the fart sounds you have gathered from step 1. You can also set the properties for each list item, I have chosen text size 14 and centered. Click OK when finished.

http://i90.photobucket.com/albums/k2...ist_widget.png

Step 4:
Left click on the Push Button widget, and change it’s name to ‘pushbutton’ in the Property Editor. I have also changed the font size to 33 and the text to read “Fart!”. In addition, by clicking on the styleSheet property you can bring up the Style Sheet Editor widget window to assign a colour to the button, in this case I have chosen a dangerous hue of red.

http://i90.photobucket.com/albums/k2...tyle_sheet.png

Step 5:
That is the GUI designed, save (File->Save As) the project as maeFart.ui and close down Qt Designer out of your way. Next we use pyuic4 to generate our python code. Open up a command line prompt, and CD into the folder you have saved the maeFart.ui file. From there, type:

Code:

pyuic4 maeFart.ui -o maeFart.py
http://i90.photobucket.com/albums/k2...nal/pyuic4.png

Step 6:
We now have our python GUI, we need a main to call it. Create a new python file called main.py and copy in the following code:

Code:

#!/usr/bin/python2.5
import sys
from PyQt4 import QtGui,QtCore
from maeFart import *

class MyForm(QtGui.QMainWindow):
        def __init__(self, parent=None):
                #build parent user interface
                QtGui.QWidget.__init__(self, parent)
                self.ui = Ui_MainWindow()
                self.ui.setupUi(self)
                #set the first item in the soundList as the currently selected fart sound
                self.ui.soundList.setCurrentRow(0)       

if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        myapp = MyForm()
        myapp.show()
        sys.exit(app.exec_())


Step7:
Qt uses the Phonon multimedia framework and can playback most of the common multimedia formats. The architecture of Phonon is that, when playing back audio, you create a media object and connect it via a path to an audio output node, which ouputs audio to the sound card or device.

http://www.riverbankcomputing.co.uk/...nceptaudio.png

First step to using phonon is to import it into our project, so at the top add:

Code:

from PyQt4.phonon import Phonon
The we create the media object and the audio output in the initialization, by placing these lines just below the GUI setup commands:

Code:

                self.m_media = Phonon.MediaObject(self)
                audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
                Phonon.createPath(self.m_media, audioOutput)

Step 8:
Connecting the button. We will write a method called playFart(), triggered by the pushButton, that will play the fart sound. First we need to hook up the “clicked()” signal of the button to call the method as so:

Code:

QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.playFart)
Step 9:
Implementing the playFart method by adding the following code to the main.py file

Code:

def playFart(self):
            #get the file name of the selected fart sound
                fart=self.farts[str(self.ui.soundList.currentItem().text())]
          self.m_media.setCurrentSource(Phonon.MediaSource(fart))
                self.m_media.play()

The first line reads the currently selected item from the list menu, converts it to a python string (using str() ), and uses that string as a key to return the file name from a dictionary called ‘farts’.

Code:

self.farts={
                "Little Fart":"fart1.wav", "Brown Fart":"fart2.wav",
                "Wet Fart":"fart3.wav", "Baby Fart":"fart4.wav",
                "Lots of Farts":"fart5.wav"
                }

In Java or C++ we might have used a CASE or switch statement, however Python does not have this functionality. A series of “if.. else” could have been used, but in this case a dictionary just seemed neater to me.

In this case the dictionary only contains keys and the associated filenames as the sound files will be placed in the same folder as the main.py file, otherwise the path would also need to be added to the filenames.

Step 10:
The completed files maeFart.py and main.py should look as follows, test them out locally and make sure everything is ok.

main.py
Code:

#!/usr/bin/python2.5
import sys
from PyQt4 import QtGui,QtCore
from PyQt4.phonon import Phonon
from maeFart import *

class MyForm(QtGui.QMainWindow):
        def __init__(self, parent=None):
                #build parent user interface
                QtGui.QWidget.__init__(self, parent)
                self.ui = Ui_MainWindow()
                self.ui.setupUi(self)
                self.ui.soundList.setCurrentRow(0)
                self.m_media = Phonon.MediaObject(self)
                audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)
                Phonon.createPath(self.m_media, audioOutput)
                #connect buttons
                QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.playFart)
               
                self.farts={
                        "Little Fart":"fart1.wav", "Brown Fart":"fart2.wav",
                        "Wet Fart":"fart3.wav", "Baby Fart":"fart4.wav",
                        "Lots of Farts":"fart5.wav"
                        }
               
        def playFart(self):
                fart=self.farts[str(self.ui.soundList.currentItem().text())]
                self.m_media.setCurrentSource(Phonon.MediaSource(fart))
                self.m_media.play()
                       

if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        myapp = MyForm()
        myapp.show()
        sys.exit(app.exec_())

maeFart.py
Code:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'maeFart.ui'
#
# Created: Fri May 28 22:49:14 2010
#      by: PyQt4 UI code generator 4.7
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 400)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtGui.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(50, 0, 701, 361))
        self.frame.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtGui.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.pushButton = QtGui.QPushButton(self.frame)
        self.pushButton.setGeometry(QtCore.QRect(410, 60, 231, 221))
        font = QtGui.QFont()
        font.setPointSize(33)
        self.pushButton.setFont(font)
        self.pushButton.setStyleSheet("background-color: rgb(255, 0, 0);")
        self.pushButton.setObjectName("pushButton")
        self.soundList = QtGui.QListWidget(self.frame)
        self.soundList.setGeometry(QtCore.QRect(60, 10, 256, 341))
        self.soundList.setObjectName("soundList")
        QtGui.QListWidgetItem(self.soundList)
        QtGui.QListWidgetItem(self.soundList)
        QtGui.QListWidgetItem(self.soundList)
        QtGui.QListWidgetItem(self.soundList)
        QtGui.QListWidgetItem(self.soundList)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "maeFart", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "Fart!", None, QtGui.QApplication.UnicodeUTF8))
        __sortingEnabled = self.soundList.isSortingEnabled()
        self.soundList.setSortingEnabled(False)
        self.soundList.item(0).setText(QtGui.QApplication.translate("MainWindow", "Little Fart", None, QtGui.QApplication.UnicodeUTF8))
        self.soundList.item(1).setText(QtGui.QApplication.translate("MainWindow", "Brown Fart", None, QtGui.QApplication.UnicodeUTF8))
        self.soundList.item(2).setText(QtGui.QApplication.translate("MainWindow", "Wet Fart", None, QtGui.QApplication.UnicodeUTF8))
        self.soundList.item(3).setText(QtGui.QApplication.translate("MainWindow", "Baby Fart", None, QtGui.QApplication.UnicodeUTF8))
        self.soundList.item(4).setText(QtGui.QApplication.translate("MainWindow", "Lots of Farts", None, QtGui.QApplication.UnicodeUTF8))
        self.soundList.setSortingEnabled(__sortingEnabled)

Step 11:
Use WinSCP and OpenSSH to transfer the files into your N900’s Opt directory. To run, open Xterm and cd into the opt directory and run the main.py file.

Code:

cd /opt
python main.py

The application will open in a new window...
http://i90.photobucket.com/albums/k2...528-230425.png

That's it for now.. happy farting!

topet2k12001 2011-07-01 16:04

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Nice. :) I'd like to learn how to do that kind of stuff.

Dave999 2013-02-04 12:34

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Great app. Even better than you last ones for n9 ;)

Great start if anyone trying to start a PyQt career.

Do you want me to port it n9?

stickymick 2013-02-04 13:36

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Quote:

Originally Posted by Dave999 (Post 1320700)
Do you want me to port it n9?

Don't you mean fart it across? :D

Might give this a go, might put some wind into my sails to start developing on a small scale. :rolleyes:

rcolistete 2013-02-04 15:44

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Quote:

Originally Posted by Dave999 (Post 1320700)
Great start if anyone trying to start a PyQt career.

PyQt (with QtWidgets) don't work* on MeeGo Harmattan. Use Qt/Qt Quick (with C/C++ or Python) instead.

(*) : no vkb, small fonts, etc.

MartinK 2013-02-04 16:39

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Quote:

Originally Posted by rcolistete (Post 1320743)
PyQt (with QtWidgets) don't work* on MeeGo Harmattan. Use Qt/Qt Quick (with C/C++ or Python) instead.

(*) : no vkb, small fonts, etc.

Actually, there is only PySide available for Harmattan so far & it supports writing both classic QtWidget & QtQuick applications.

And yes, you should use QtQuick if possible, due to the issues QtWidgets have as mentioned by rcolistete.

nokiabot 2013-07-09 08:06

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Wow with the help of kojackers nobel ideas and his innovative coding skills my n900 now can fart :D wish it could produce pleasent aromatic feeling also:D just a feature request : using the front camera or back camera to fart. So that i can keep the phone on sofa and when somebody sits beside it would fart:D

kojacker 2013-07-09 12:57

Re: Build a simple Fart App in 30 Mins! N900, PyQt
 
Quote:

Originally Posted by nokiabot (Post 1357813)
Wow with the help of kojackers nobel ideas and his innovative coding skills my n900 now can fart :D wish it could produce pleasent aromatic feeling also:D just a feature request : using the front camera or back camera to fart. So that i can keep the phone on sofa and when somebody sits beside it would fart:D

Oh gosh, I wish this old thread would die! lol

Using a camera would need a bunch of image processing, I guess, to detect the person moving past. Even easier might be to leave the phone on the sofa and use the accelerometer code from maeHammer (part 2 of the tutorial here - 'rt2 - adding sound and accelerometer with maeHammer') to play back the noise when the phone is moved/jolted when the victim sits down. Just make sure you don't hide the phone too well or the person may sit down on top of it ;)


All times are GMT. The time now is 21:24.

vBulletin® Version 3.8.8