[PA-03a] Create GUI with Qt

In this tutorial, we focus on building a GUI that gives command to Arduino and Arduino will display the received command, turn Led on-off and give feedback message. The main content will how to use Qt to make GUI. Easy thing on first, here is the code of Arduino
pyqt_blink_feedback.ino


/*
 * Date: Fri, 05/05/2017
 * Desc: Blink Led 13 when receiving command
 * and give feedback message
 * also display lcd i2c command
 */
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x3F 
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

// Used for pin status
int ledPin = 13;

// Used for serial 
char incomingChar;

void setup() {
 // Initial process
 delay(1000);
 pinMode(ledPin, OUTPUT); // declare LED as output
 digitalWrite(ledPin, LOW);
 Serial.begin(9600);
 Serial.println("Ready for command.");

lcd.begin(16,2);
 lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
 lcd.setBacklight(HIGH);
 lcd.clear();
 lcd.print("Waiting command:");
}

void loop(){
 // when characters arrive over the serial port...
 if (Serial.available()){
 // wait a bit for the entire message to arrive
 delay(100);
 while (Serial.available() > 0) {
 incomingChar = Serial.read();
 lcd_display_command(String(incomingChar));
 if (incomingChar == '1'){ 
 digitalWrite(ledPin, HIGH);
 Serial.println("Led is turn on."); 
 } else if (incomingChar == '0'){
 digitalWrite(ledPin, LOW);
 Serial.println("Led is turn off."); 
 } else {
 Serial.println("Error.");
 }
 // Post processing, clear incomingChar
 incomingChar = ' ';
 }
 }
}

void lcd_display_command(String content){
 lcd.clear();
 lcd.print("Received command");
 lcd.setCursor(0,1);
 lcd.print(content);
}

Step 1: download PyQt 4.10 x32 at SourceForge URL: https://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10/PyQt4-4.10-gpl-Py2.7-Qt4.8.4-x32.exe/download and install to your computer

Step 2: create folder pyqt_blink_command

Open Qt designer, New Form will show up --> pick Dialog without Button --> Create.

Step 2.1: modify the windowTitle of Dialog into Control Led with feedback

Step 2.2: create Text Browser --> Drag and Drop TextBrowser (Display Widget) to Dialog

Step 2.3: create Button --> Drag and Drop PushButton to Dialog --> change Text to Turn on (because initially Led 13 is off)

Step 2.4: save form with name ArduinoLed.ui in folder pyqt_blink_command

Step 3: cmd --> change directory to folder pyqt_blink_command --> convert file .ui to file .py


pyuic4 -x ArduinoLed.ui -o ArduinoLedUI.py

Right click on ArduinoLedUI.py --> Edit with IDLE. We can Run this code for testing first.

Step 4: modify code that is converted from .ui, including: import serial library, write function for button and display the feedback message

Step 4.1: import the serial library at the beginning of the code

[modified ArduinoLedUI.py]


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

# Form implementation generated from reading ui file 'ArduinoLed.ui'
#
# Created: Fri May 05 14:43:31 2017
# by: PyQt4 UI code generator 4.10
#
# WARNING! All changes made in this file will be lost!

import sys, time, serial
from PyQt4 import QtCore, QtGui

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

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)

class Ui_Dialog(object):
 def setupUi(self, Dialog):
 # declaration for serial port and initialize variable
 self.LedStatus = 0 # Led status showing on-off
 self.arduino = serial.Serial('COM3', 9600)
 txtArduino = self.arduino.readline()
 txt = "Arduino> " + txtArduino
 #
 Dialog.setObjectName(_fromUtf8("Dialog"))
 Dialog.resize(401, 223)
 self.textBrowser = QtGui.QTextBrowser(Dialog)
 self.textBrowser.setGeometry(QtCore.QRect(10, 10, 381, 141))
 self.textBrowser.setObjectName(_fromUtf8("textBrowser"))
 # Set initial content of Text Browser
 self.textBrowser.append(txt)
 #
 self.pushButton = QtGui.QPushButton(Dialog)
 self.pushButton.setGeometry(QtCore.QRect(280, 160, 111, 41))
 self.pushButton.setObjectName(_fromUtf8("pushButton"))

self.retranslateUi(Dialog)
 QtCore.QMetaObject.connectSlotsByName(Dialog)
 # Set the event for button when being clicked
 QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL("clicked()"), self.LedControl)

def retranslateUi(self, Dialog):
 Dialog.setWindowTitle(_translate("Dialog", "Control Led with feedback", None))
 self.pushButton.setText(_translate("Dialog", "Turn on", None))

# Function for exit
 def quit(self):
 sys.exit(app.exec_())

# Function for clicking event
 def LedControl(self):
 if self.LedStatus==0:
 self.LedStatus = 1
 self.pushButton.setText('Turn off')
 self.arduino.write('1')
 txtArduino = self.arduino.readline()
 else:
 self.LedStatus = 0
 self.pushButton.setText('Turn on')
 self.arduino.write('0')
 txtArduino = self.arduino.readline()
 txt = "Arduino> " + txtArduino
 self.textBrowser.append(txt)

if __name__ == "__main__":
 import sys
 app = QtGui.QApplication(sys.argv)
 Dialog = QtGui.QDialog()
 ui = Ui_Dialog()
 ui.setupUi(Dialog)
 Dialog.show()
 sys.exit(app.exec_())

Tabspace will determine the structure of python code so be careful when copying and pasting the following code to your project.

Leave a comment