Lab3_Gui code

Dependencies:   mbed

mbed_beat_new.py

Committer:
dogcatfee
Date:
2017-09-21
Revision:
1:faa8aa177069

File content as of revision 1:faa8aa177069:

#*****************************************************************#
#                                                                 #
#   File: beatfactorygui.py                                       #
#   Author: Ethan Takla                                           #
#   Date Created: 10/6/14                                         #
#   Description: A python GUI for graphically creating songs on   #
#                the FDRM-KL46z                                       #
#                                                                 #
#*****************************************************************#
# Last edit: Matthew Sessions

#System Imports
import sys

#Serial Imports
import serial
from serial.tools import list_ports

#Signal Imports
import signal

#Sound Imports

# Uncomment for sound
#import winsound

#Threading imports
import thread

#PyQt Imports
from PyQt4.QtGui import QApplication, QDialog, QMainWindow, QFileDialog
from PyQt4 import QtCore, QtGui


try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

#Setup text encoding
try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

#Create Note Classs
class Note:
    def __init__( self, note ):
        self.note = note

#Main Window Class
class Ui_MainWindow(QtGui.QMainWindow):

    def initializeUI(self, MainWindow):

        #Initialize main window properties
        MainWindow.setObjectName(_fromUtf8("FDRM-KL46z Beat Factory"))
        MainWindow.resize(1200, 848)
        MainWindow.setMaximumSize(QtCore.QSize(16777215, 848))

        #Create central widget
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))

        #Create gridLayout_2
        self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))

        #Create and format a graphics view widget
        self.graphicsView = QtGui.QGraphicsView(self.centralwidget)
        self.graphicsView.setMinimumSize(QtCore.QSize(300, 120))
        self.graphicsView.setMaximumSize(QtCore.QSize(300, 120))
        self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        #Set the graphics view image
        self.scene = QtGui.QGraphicsScene();
        self.pixmap = QtGui.QPixmap( "TekBots.png" )
        self.scene.addPixmap(self.pixmap)
        self.graphicsView.setScene( self.scene )
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

        #Add the graphics view to gridLayout_2
        self.gridLayout_2.addWidget(self.graphicsView, 0, 1, 1, 1)

        #Create and format verticalLayout_2
        self.verticalLayout_2 = QtGui.QVBoxLayout()
        self.verticalLayout_2.setSpacing(7)
        self.verticalLayout_2.setSizeConstraint(QtGui.QLayout.SetNoConstraint)
        self.verticalLayout_2.setContentsMargins(-1, -1, -1, 0)
        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))

        #Create a table view for beat editing
        self.tableView = QtGui.QTableWidget(self.centralwidget)

        #Add the table view to verticalLayout2
        self.verticalLayout_2.addWidget(self.tableView)

        #Add verticalLayout2 to gridLayout2
        self.gridLayout_2.addLayout(self.verticalLayout_2, 0, 0, 7, 1)

        #Create gridLayout
        self.gridLayout = QtGui.QGridLayout()
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))

        #Create and format pushButton, add them to gridLayout
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.setStyleSheet("color: black; background-color: red;")
        self.gridLayout.addWidget(self.pushButton, 0, 2, 1, 1)
        self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_2.setEnabled( False )
        self.gridLayout.addWidget(self.pushButton_2, 3, 0, 1, 1)
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_3.setEnabled( False )
        self.gridLayout.addWidget(self.pushButton_3, 3, 1, 1, 1)

        #Create labels and add them to gridLayout
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setObjectName(_fromUtf8("label"))
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.label2 = QtGui.QLabel(self.centralwidget)
        self.label2.setObjectName(_fromUtf8("label2"))
        self.gridLayout.addWidget(self.label2, 1, 0, 1, 1)
        self.label3 = QtGui.QLabel(self.centralwidget)
        self.label3.setObjectName(_fromUtf8("label3"))
        self.gridLayout.addWidget(self.label3, 2, 0, 1, 1)

        #Create comboBoxs and add them to gridLayout
        self.comboBox = QtGui.QComboBox(self.centralwidget)
        self.comboBox.setObjectName(_fromUtf8("comboBox"))
        self.gridLayout.addWidget(self.comboBox, 0, 1, 1, 1)
        self.comboBox2 = QtGui.QComboBox(self.centralwidget)
        self.comboBox2.setObjectName(_fromUtf8("comboBox2"))
        self.gridLayout.addWidget(self.comboBox2, 1, 1, 1, 1)
        self.comboBox3 = QtGui.QComboBox(self.centralwidget)
        self.comboBox3.setObjectName(_fromUtf8("comboBox3"))
        self.gridLayout.addWidget(self.comboBox3, 2, 1, 1, 1)
        
        #Add gridLayout to gridLayout_2 and format
        self.gridLayout_2.addLayout(self.gridLayout, 1, 1, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)

        #Create and configure the menu bar
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 972, 26))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuHelp = QtGui.QMenu(self.menubar)
        self.menuHelp.setObjectName(_fromUtf8("menuHelp"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        #Create a QAction for the Load and Save songs, and About button
        self.actionLoad_Song = QtGui.QAction(MainWindow)
        self.actionLoad_Song.setObjectName(_fromUtf8("actionLoad_Song"))
        self.actionSave_Song = QtGui.QAction(MainWindow)
        self.actionSave_Song.setObjectName(_fromUtf8("actionSave_Song"))
        self.actionAbout = QtGui.QAction(MainWindow)
        self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
        self.menuFile.addAction(self.actionLoad_Song)
        self.menuFile.addAction(self.actionSave_Song)
        self.menuHelp.addAction(self.actionAbout)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        #Set text of all UI elements
        self.retranslateUI(MainWindow)

        #Connect Slots
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        #Populate comboBox3 and configure tempo
        self.comboBox3.clear()
        self.comboBox3.addItems(self.tempoValues)
        self.comboBox3.setCurrentIndex( 14 )
        self.tempo = 120

        #Populate Combobox 2
        self.comboBox2.clear()
        self.comboBox2.addItems(self.noteNumberValues)

    def retranslateUI(self, MainWindow):

        #Set the text of the UI elements
        MainWindow.setWindowTitle(_translate("FDRM-KL46z Beat Factory", "FDRM-KL46z Beat Factory", None))
        self.pushButton.setText(_translate("FDRM-KL46z Beat Factory", "Scan", None))
        self.pushButton_2.setText(_translate("FDRM-KL46z Beat Factory", "Play", None))
        self.pushButton_3.setText(_translate("FDRM-KL46z Beat Factory", "Clear", None))
        self.label.setText(_translate("FDRM-KL46z Beat Factory", "COM Port:", None))
        self.label2.setText(_translate("FDRM-KL46z Beat Factory", "Number of Notes:", None))
        self.label3.setText(_translate("FDRM-KL46z Beat Factory", "Tempo:", None))
        self.menuFile.setTitle(_translate("FDRM-KL46z Beat Factory", "File", None))
        self.menuHelp.setTitle(_translate("FDRM-KL46z Beat Factory", "Help", None))
        self.actionLoad_Song.setText(_translate("FDRM-KL46z Beat Factory", "Load Song", None))
        self.actionSave_Song.setText(_translate("FDRM-KL46z Beat Factory", "Save Song", None))
        self.actionAbout.setText(_translate("FDRM-KL46z Beat Factory", "About", None))

    def initializeVariables( self ):

        #Define cell selected/unselected variables
        self.cellSelected = 1
        self.cellUnselected = 0

        #Set initial comm. state
        self.comButtonState = "Scan"

        #Create the song array
        self.song_array = []    # delete all note elements
                
        #Set table row and column count variables
        self.tableViewRowCount = 24
        self.tableViewColumnCount = 16
        self.selectedCells = [[0 for x in xrange(self.tableViewColumnCount)] for x in xrange(self.tableViewRowCount)]
        self.noteFrequencies = [ 831, 784, 740, 698, 659, 622, 587, 554, 523, 494, 466, 440, 415, 392, 370, 349, 330, 311, 294, 277, 261, 247, 233, 220 ]

        #Define tempo values
        self.tempoValues = [ "50", "55", "60", "65", "70", "75", "80", "85", "90", "95", "100", "105", "110", "115", "120", "125", "130",
                             "135", "140", "145", "150", "155", "160", "165", "170", "175", "180", "185", "190", "195", "200", "205",
                             "210", "215", "220", "225", "230", "235", "240"]

        #Define note number values
        self.noteNumberValues = [ "16", "32", "48", "64" ]

        #Define serial ports that are to be 'detected' 
        self.ports = [ "Select",
                       'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9', 'COM10',
                       'COM11', 'COM12', 'COM13', 'COM14', 'COM15', 'COM16', 'COM17', 'COM18',
                       'COM19', 'COM20', 'COM21', '/dev/ttyACM0', '/dev/ttyACM1', '/dev/ttyACM2', '/dev/ttyACM3']
        

        
    def initializeTable( self ):
        
        #Initialize beat table columns and rows
        self.tableView.setColumnCount(self.tableViewColumnCount)
        self.tableView.setRowCount(self.tableViewRowCount)

        #Initialize beat table rows for notes
        self.verticalHeaderLabels = [ "G#", "G", "F#", "F", "E", "D#", "D", "C#", "C(High)", "B", "A#", "A", "G#", "G", "F#", "F", "E", "D#", "D", "C#", "C (Middle)", "B", "A#", "A" ]

        #Label vertical headers on table
        self.tableView.setVerticalHeaderLabels( self.verticalHeaderLabels )
        
        #Make table ready only by creating items widgets in each cell and disabling them
        for i in xrange(self.tableView.rowCount()):
            for j in xrange(self.tableView.columnCount()):  
                self.tableView.setItem(i,j, QtGui.QTableWidgetItem())
                self.tableView.item(i,j).setFlags(QtCore.Qt.ItemIsEnabled)
        
    def initializeSerial( self ):

        #Configure the serial port for 8-N-1, baudrate doesn't matter since the FDRM-KL46z is running a VCP
        self.ser = serial.Serial()
        self.ser.timeout = 1000
        self.ser.baudrate = 9600
        
    def highlightColumn( self, column ):
        
        #Go through the unselected cells in each row and highlight them
        for i in xrange(self.tableView.rowCount()):
            if self.selectedCells[i][column] == self.cellUnselected:
                self.tableView.item(i, column).setBackground(QtGui.QColor(255,179,0))
                
    def unhighlightColumn( self, column ):

        #Go through the unselected cells in each row and unhighlight them
        for i in xrange(self.tableView.rowCount()):
            if self.selectedCells[i][column] == self.cellUnselected:
                self.tableView.item(i, column).setBackground(QtGui.QColor(255,255,255))
                
    def handlePlayButton( self ):

        #Disable play and clear buttons while song is playing
        self.pushButton_2.setEnabled( False )
        self.pushButton_3.setEnabled( False )

        #Empty song array
        del self.song_array[:]
        emptyCells = 0

        
        for j in xrange(self.tableView.columnCount()):
            for i in xrange(self.tableView.rowCount()):

                #If a cell is selected, add the corresponding note to the song array
                if self.selectedCells[i][j] == self.cellSelected:
                    
                    #Store the note index
                    note_name = i # note name is letter A-G 
            
                    # create Note class and populate
                    note = Note( note_name )
                    self.song_array.append( note )                  # add Note to array of Notes        
                else:
                    emptyCells += 1

                #If an empty column is found, add a rest (index 24) to the song array
                if emptyCells == self.tableView.rowCount():
                    
                    # store user-inputted note into a Note class
                    note_name = 24 # note name is letter A-G 
            
                    # create Note class and populate
                    note = Note( note_name )
                    self.song_array.append( note )                  # add Note to array of Notes

            emptyCells = 0
                
        
        try:
            self.ser.open()
        except:
            self.serialScan()
            return
        self.ser.write( "$NEW\n" )                                  #Send new song packet
        self.ser.write( "$T" )                                      #Send Tempo Packet
        self.ser.write( "%d" % (self.tempo*4) )       
        self.ser.write( '\n' )                          
        self.ser.write( "$L" )                                      #Send song length packet
        self.ser.write( "%d" % (self.tableView.columnCount() ) )   
        self.ser.write( '\n' )                    
        for i in range(self.tableView.columnCount()):               
            self.ser.write( "$S" )                                  #Send note data packet
            self.ser.write( "%d" % (self.song_array[i].note) )
            self.ser.write( '\n' )                  
        self.ser.write( "$PLAY\n" )                                 #Send play song packet
        
        data = 0
        
        while 1:

            #Wait for serial data to be available
            if self.ser.inWaiting() != 0:

                #Read a line of data
                data = int(self.ser.readline())

                #Exit the while loop if a termination character (0xFF) is received
                if data == 255:
                    break;

                #Highlight the column specified by the data
                self.highlightColumn( data )

                #Scroll to the column so we can see it
                self.tableView.scrollToItem( self.tableView.item(0,data) )

                #Unhighlight previous column
                if data > 0:
                    self.unhighlightColumn( data - 1 )

                #Force a GUI uptdate
                QApplication.processEvents()
                
        self.unhighlightColumn( self.tableView.columnCount()-1 )
        self.ser.close()

        #Enable play and clear buttons after song is song playing
        self.pushButton_2.setEnabled( True )
        self.pushButton_3.setEnabled( True )
                
    def handleClearButton( self ):

        #Go through each cell, make it white, and set it as unselected
        for i in xrange(self.tableView.rowCount()):
            for j in xrange(self.tableView.columnCount()):  
                self.tableView.item(i, j).setBackground(QtGui.QColor(255,255,255))
                self.selectedCells[i][j] = self.cellUnselected

    def serialScan( self ):

        #Populate the combobox with ports
        self.comboBox.clear()
        self.comboBox.addItems( self.ports )

        #Go through each port name to see if it exists
        for i in self.ports[1:]:
            self.ser.port = i
            try:
                self.ser.open()
            except Exception, e:

                #If the port name does not exist, remove it from the combobox
                remove_port = self.comboBox.findText( self.ser.port )
                self.comboBox.removeItem( remove_port )
            self.ser.close()

    def handleComButton( self ):

        #If the comm. button is is Scan mode, scan the serial ports
        if self.comButtonState == "Scan":

            self.serialScan()

            if self.comboBox.count() > 1:

                #If we have detected a serial port, change the button name to "connect" and change color
                self.pushButton.setText(_translate("MainWindow", "Connect", None))
                self.pushButton.setStyleSheet("color: black; background-color: yellow;")
                self.comButtonState = "Connect"

                #Enable the play and clear buttons
                self.pushButton_2.setEnabled( True )
                self.pushButton_3.setEnabled( True )
            else:

                #Create a message box if there was no COM port detected
                QtGui.QMessageBox.information(self, 'Error',"A serial device was not detected, please ensure that it is plugged into your computer.")
                
        elif self.comButtonState == "Connect":

            #Create a new port
            self.ser.close()
            new_port = str(self.comboBox.currentText())
            self.ser.port = new_port
            
            try:
                if self.comboBox.currentText() != "Select":
                    self.ser.open()
                else:
                    QtGui.QMessageBox.information(self, 'Error',"Please Select a COM port.")
                    
            except Exception ,e:

                #If we can't connect, reset the button state to "scan"
                self.pushButton.setText(_translate("MainWindow", "Disconnect", None))
                self.pushButton.setStyleSheet("color: black; background-color: red;")
                self.comButtonState = "Scan"
            if self.ser.isOpen():

                #If we can open the serial port, change the button name to "disconnect" and change color
                self.pushButton.setText(_translate("MainWindow", "Disconnect", None))
                self.pushButton.setStyleSheet("color: black; background-color: green;")
                self.comButtonState = "Disconnect"
                self.ser.close()
                
        elif self.comButtonState == "Disconnect":

            #Change the button text to "Scan" once disconnect it pressed, and change color
            self.pushButton.setText(_translate("MainWindow", "Scan", None))
            self.pushButton.setStyleSheet("color: black; background-color: red;")
            self.comButtonState = "Scan"

            #Disable play and clear buttons
            self.pushButton_2.setEnabled( False )
            self.pushButton_3.setEnabled( False )

    def beepThread( self, tone ):
            print "No sound"
            #Produce a tone using winsound
            
            # Uncomment below for sound
            #winsound.Beep(tone, 150)
            
    def handleCellClicked(self, row, column):

        self.noteExists = False

        #Check to see if any notes are already selected in the row
        for i in xrange(self.tableView.rowCount()):
            if self.selectedCells[i][column] == self.cellSelected:
                self.noteExists = True
                
            
        #If a cell is clicked and unselected, change it's color, mark it as selected, and start the tone thread
        if self.selectedCells[row][column] == self.cellUnselected:

            #Do not select cell if a note already exists in the column
            if self.noteExists == False:
                
                self.tableView.item(row, column).setBackground(QtGui.QColor(100,100,150))
                self.selectedCells[row][column] = self.cellSelected
                thread.start_new_thread(self.beepThread, (self.noteFrequencies[row],))

        #If a cell is clicked and selected, change it's color and mark it as unselected
        else:
            self.tableView.item(row, column).setBackground(QtGui.QColor(255,255,255))
            self.selectedCells[row][column] = self.cellUnselected

    def handleSaveSongButton( self ):

        #Create a save file dialog
        self.fileName = QFileDialog.getSaveFileName(self,"Save File",
                            "",
                            "FDRM-KL46z Song (*.song)");
        try:
            #Create a file with the filename provided from the user
            self.f = open(self.fileName, 'w')

            #Write the note number index
            self.f.write( str(self.comboBox2.currentIndex()) + '\n' )
    
            #Write each note as a coordinate on a newline
            for i in xrange(self.tableView.rowCount()):
                for j in xrange(self.tableView.columnCount()):  
                    if self.selectedCells[i][j] == self.cellSelected:
                        self.f.write( str(i)+ ',' + str(j) + '\n')

            #Write the end of song marker
            self.f.write( "end song")
            self.f.close()

        except Exception ,e:
            print(e)
            
    def handleLoadSongButton( self ):

        #Create and open file dialog
        self.fileName = QFileDialog.getOpenFileName(self,"Open File",
                            "",
                            "FDRM-KL46z Song (*.song)");

        try:
            #Open the user defined file for reading
            self.f = open(self.fileName, 'r')

            #cleat all notes from tableview
            self.handleClearButton();

            #Read index number and change the note number combo box
            index = int(self.f.readline())
            self.handleNoteNumberChange(index)
            self.comboBox2.setCurrentIndex(index)

            #Read the first cell location
            self.cellID = self.f.readline()

            #Continue reading cell ID's and activate corresponding cells
            while self.cellID != "end song":
                i = 0
                columnString = ""
                rowString = ""

                #Wait until we get a comma
                while self.cellID[i] != ',':
                    rowString += self.cellID[i]
                    i += 1

                #Go to the next data point after a newline character
                while self.cellID[i+1] != '\n':
                    columnString += self.cellID[i+1]
                    i += 1

                #Update the table view
                self.tableView.item(int(rowString), int(columnString)).setBackground(QtGui.QColor(100,100,150))
                self.selectedCells[int(rowString)][int(columnString)] = self.cellSelected
                self.cellID = self.f.readline()
        except Exception ,e:
            print(e)

    def handleNoteNumberChange( self, index ):

        #Change the number of columns in the table if the song length changes 
        self.tableViewColumnCount = int(self.noteNumberValues[int(index)])
        self.selectedCells = [[0 for x in xrange(self.tableViewColumnCount)] for x in xrange(self.tableViewRowCount)]

        #Reset the table
        self.initializeTable()
        self.handleClearButton()

    def handleTempoChange( self, index ):

        #Change necesarry variables if the tempo is chaged
        self.tempo = int(self.tempoValues[int(index)])

    def handleAboutButton( self ):

        #Opens the about form if the about button is pressed
        self.dialog = QtGui.QDialog(self)
        self.dialog.ui = aboutForm()
        self.dialog.ui.setupUi(self.dialog)
        self.dialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.dialog.show()
        
        
    def bind_events( self ):
        #Bind events to handler functions      
        self.pushButton.clicked.connect( self.handleComButton )                         
        self.tableView.cellClicked.connect( self.handleCellClicked )
        self.pushButton_3.clicked.connect( self.handleClearButton )
        self.actionSave_Song.triggered.connect( self.handleSaveSongButton )
        self.actionLoad_Song.triggered.connect( self.handleLoadSongButton )
        self.pushButton_2.clicked.connect( self.handlePlayButton )
        self.comboBox2.currentIndexChanged.connect( self.handleNoteNumberChange )
        self.comboBox3.currentIndexChanged.connect( self.handleTempoChange )
        self.actionAbout.triggered.connect( self.handleAboutButton )
        
class aboutForm(object):
        
    def setupUi(self, Form):

        #Configure the form
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(381, 233)
        Form.setMinimumSize(QtCore.QSize(381, 233))
        Form.setMaximumSize(QtCore.QSize(381, 233))

        #Create label
        self.label = QtGui.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(140, 160, 121, 16))
        self.label.setObjectName(_fromUtf8("label"))

        #Create label_2
        self.label_2 = QtGui.QLabel(Form)
        self.label_2.setGeometry(QtCore.QRect(140, 180, 121, 16))
        self.label_2.setObjectName(_fromUtf8("label_2"))

        #Create label_3
        self.label_3 = QtGui.QLabel(Form)
        self.label_3.setGeometry(QtCore.QRect(160, 200, 121, 16))
        self.label_3.setObjectName(_fromUtf8("label_3"))

        #Create a graphics view
        self.graphicsView = QtGui.QGraphicsView(Form)
        self.graphicsView.setGeometry(QtCore.QRect(40, 20, 300, 120))
        self.graphicsView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.graphicsView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

        #Set the graphics view image
        self.scene = QtGui.QGraphicsScene();
        self.pixmap = QtGui.QPixmap( "TekBots.png" )
        self.scene.addPixmap(self.pixmap)
        self.graphicsView.setScene( self.scene )
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))

        #Set text of all UI elements
        self.retranslateUi(Form)

        #Connect Slots
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):

        #Set text of all UI elements
        Form.setWindowTitle(_translate("About", "About", None))
        self.label.setText(_translate("About", "FDRM-KL46z Beat Factory", None))
        self.label_2.setText(_translate("About", "Author: Ethan Takla", None))
        self.label_3.setText(_translate("About", "Revision 0.1", None))
        
#Start the app        
app = QApplication(sys.argv)
window = QMainWindow()
ui = Ui_MainWindow()
ui.initializeVariables()
ui.initializeUI(window)
ui.initializeTable()
ui.initializeSerial()
ui.bind_events()

window.show()
sys.exit(app.exec_())