POSTS
Week 13: Interface/application progamming
I used pyqt to create a simple GUI to interface with my OLED screen. The user can type in values to a text box and click a button that sends these values to an OLED screen.
I had to import QtWidgets like this and then write QtWidgets.QApplication..etc
from PyQt5 import QtWidgets
instead of like this because of an error I was getting with the way I installed pyqt on my linux machine (it was something to do with pylint not pyqt itself (pylint is a code cleaning tool))
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox
Here’s the rest of the python, the code below is mainly setting up the GUI and layout/colors.:
app = QtWidgets.QApplication([])
app.setStyle('Fusion')
app.setStyleSheet("QPushButton { margin: 10ex; }")
# palette = QtWidgets.QPalette()
# palette.setColor(QtWidgets.QPalette.ButtonText, QtWidgets.Qt.red)
# app.setPalette(palette)
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(QtWidgets.QPushButton('Top'))
layout.addWidget(QtWidgets.QPushButton('Bottom'))
window.setLayout(layout)
window.show()
button = QtWidgets.QPushButton('Click')
def on_button_clicked():
alert = QtWidgets.QMessageBox()
alert.setText('You clicked the button!')
alert.exec_()
button.clicked.connect(on_button_clicked)
button.show()
app.exec_()
Here’s an image of this GUI I was doing some basic testing with. Not super pretty but easy to work with.
To make things cleaner, I used a more object oriented approach(found code on this link: https://pythonspot.com/pyqt5-textbox-example/). The class and instances make it easier to build on the GUI and automate things.
import sys
from PyQt5 import QtWidgets
# from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox
from PyQt5 import QtGui
from PyQt5 import QtCore
# from PyQt5.QtGui import QIcon
# from PyQt5.QtCore import pyqtSlot
class App(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.title = 'PyQt5 textbox - pythonspot.com'
self.left = 10
self.top = 10
self.width = 400
self.height = 140
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
# Create textbox
self.textbox = QtWidgets.QLineEdit(self)
self.textbox.move(20, 20)
self.textbox.resize(280,40)
# Create a button in the window
self.button = QtWidgets.QPushButton('Show text', self)
self.button.move(20,80)
# connect button to function on_click
self.button.clicked.connect(self.on_click)
self.show()
@QtCore.pyqtSlot()
def on_click(self):
textboxValue = self.textbox.text()
QtWidgets.QMessageBox.question(self, 'Message - pythonspot.com', "You typed: " + textboxValue, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Ok)
self.textbox.setText("")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Here’s the updated GUI with a text box:
Here is a code chunk to connect to, read to, and write to a serial port:
from PyQt5 import QtCore, QtWidgets, QtSerialPort
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.message_le = QtWidgets.QLineEdit()
self.send_btn = QtWidgets.QPushButton(
text="Send",
clicked=self.send
)
self.output_te = QtWidgets.QTextEdit(readOnly=True)
self.button = QtWidgets.QPushButton(
text="Connect",
checkable=True,
toggled=self.on_toggled
)
lay = QtWidgets.QVBoxLayout(self)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.message_le)
hlay.addWidget(self.send_btn)
lay.addLayout(hlay)
lay.addWidget(self.output_te)
lay.addWidget(self.button)
self.serial = QtSerialPort.QSerialPort(
'/dev/ttyUSB0',
baudRate=QtSerialPort.QSerialPort.Baud115200,
readyRead=self.receive
)
@QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.output_te.append(text)
@QtCore.pyqtSlot()
def send(self):
self.serial.write(self.message_le.text().encode())
@QtCore.pyqtSlot(bool)
def on_toggled(self, checked):
self.button.setText("Disconnect" if checked else "Connect")
if checked:
if not self.serial.isOpen():
if not self.serial.open(QtCore.QIODevice.ReadWrite):
self.button.setChecked(False)
else:
self.serial.close()
Testing the GUI by connecting and writing to the serial port:
self.serial = QtSerialPort.QSerialPort(
'/dev/ttyACM0',
baudRate=QtSerialPort.QSerialPort.Baud9600,
readyRead=self.receive
)
The code chunk above is important:
I had issues when connecting to my board but realized I was running the wrong baud rate (9600) when I needed to be running at 115200.
I also wrote /dev/ttyACM0 at first, and my board is called ttyUSB0, so I was debugging for a while just because I was connecting to the wrong serial port.
Finally I connected to my board (old board with a potentiometer from several weeks ago) and connected to the GUI!