Reputation: 627
I want a program, to send and recive data from an Arduino, I have made a GUI with PyQt5, but I have a problem. I have two comboboxes, one for select port, and other to select baudrate, I have implement a function for choosing baudrate, but I do not know hoe to send port name from my first combobox to function "defineSerial"can anyoane help me?
from PyQt5 import QtCore, QtWidgets, QtSerialPort
from PyQt5.uic import loadUi
class Widget(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
loadUi('/Users/bogdanvesa/P2A_GUI/mainwindow.ui', self)
self.lcd_StartBtn.clicked.connect(self.send)
self.connect_btn.clicked.connect(self.connectToPort)
self.disconnect_btn.clicked.connect(self.disconnectFromPort)
self.baudrate_comboBox.addItem("1200")
self.baudrate_comboBox.addItem("2400")
self.baudrate_comboBox.addItem("4800")
self.baudrate_comboBox.addItem("9600")
self.baudrate_comboBox.currentTextChanged.connect(self.defineSerial)
def defineSerial(self, text):
if text == '1200':
self.baudrate = QtSerialPort.QSerialPort.Baud1200
elif text == '2400':
self.baudrate = QtSerialPort.QSerialPort.Baud2400
elif text == '4800':
self.baudrate = QtSerialPort.QSerialPort.Baud4800
elif text == '9600':
self.baudrate = QtSerialPort.QSerialPort.Baud9600
else:
print("Invalid")
self.serial = QtSerialPort.QSerialPort\
(
'/dev/tty.usbmodem14201',
baudRate= self.baudrate,
readyRead=self.receive
)
@QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.light_lineEdit.setText(text)
print(text)
@QtCore.pyqtSlot()
def send(self):
self.serial.write(self.lcd_lineEdit.text().encode())
@QtCore.pyqtSlot()
def connectToPort(self):
self.serial.open(QtCore.QIODevice.ReadWrite)
@QtCore.pyqtSlot(bool)
def disconnectFromPort(self):
self.serial.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Upvotes: 1
Views: 2423
Reputation: 243887
It is better to have a QDialog to configure so when you open that dialog the available ports will be refreshed:
from PyQt5 import QtCore, QtWidgets, QtSerialPort
class Dialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
self.portname_comboBox = QtWidgets.QComboBox()
self.baudrate_comboBox = QtWidgets.QComboBox()
for info in QtSerialPort.QSerialPortInfo.availablePorts():
self.portname_comboBox.addItem(info.portName())
for baudrate in QtSerialPort.QSerialPortInfo.standardBaudRates():
self.baudrate_comboBox.addItem(str(baudrate), baudrate)
buttonBox = QtWidgets.QDialogButtonBox()
buttonBox.setOrientation(QtCore.Qt.Horizontal)
buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
lay = QtWidgets.QFormLayout(self)
lay.addRow("Port Name:", self.portname_comboBox)
lay.addRow("BaudRate:", self.baudrate_comboBox)
lay.addRow(buttonBox)
self.setFixedSize(self.sizeHint())
def get_results(self):
return self.portname_comboBox.currentText(), self.baudrate_comboBox.currentData()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.lcd_StartBtn = QtWidgets.QPushButton(
"Send",
clicked=self.send
)
self.lcd_lineEdit = QtWidgets.QLineEdit()
self.light_lineEdit = QtWidgets.QLineEdit(readOnly=True)
self.connect_btn = QtWidgets.QPushButton(
"Connect",
clicked=self.connectToPort
)
self.disconnect_btn = QtWidgets.QPushButton(
"Disconnect",
clicked=self.disconnectFromPort
)
self.configure_btn = QtWidgets.QPushButton(
"Configure",
clicked=self.open_dialog
)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
lay = QtWidgets.QFormLayout(central_widget)
lay.addRow(self.connect_btn)
lay.addRow(self.disconnect_btn)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.lcd_lineEdit)
hlay.addWidget(self.lcd_StartBtn)
lay.addRow(hlay)
lay.addWidget(self.light_lineEdit)
lay.addRow(self.configure_btn)
self.serial = QtSerialPort.QSerialPort(
self,
readyRead=self.receive
)
@QtCore.pyqtSlot()
def open_dialog(self):
dialog = Dialog()
if dialog.exec_():
portname, baudrate = dialog.get_results()
self.serial.setPortName(portname)
self.serial.setBaudRate(baudrate)
@QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.light_lineEdit.setText(text)
print(text)
@QtCore.pyqtSlot()
def send(self):
self.serial.write(self.lcd_lineEdit.text().encode())
@QtCore.pyqtSlot()
def connectToPort(self):
self.serial.open(QtCore.QIODevice.ReadWrite)
@QtCore.pyqtSlot(bool)
def disconnectFromPort(self):
self.serial.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
If you still want to continue using your logic then the big question is: When do you need e portname and baudrate? Both parameters are needed in the connection.
from PyQt5 import QtCore, QtWidgets, QtSerialPort, uic
class Widget(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
uic.loadUi('/Users/bogdanvesa/P2A_GUI/mainwindow.ui', self)
self.lcd_StartBtn.clicked.connect(self.send)
self.connect_btn.clicked.connect(self.connectToPort)
self.disconnect_btn.clicked.connect(self.disconnectFromPort)
self.baudrate_comboBox.addItem("1200", QtSerialPort.QSerialPort.Baud1200)
self.baudrate_comboBox.addItem("2400", QtSerialPort.QSerialPort.Baud2400)
self.baudrate_comboBox.addItem("4800", QtSerialPort.QSerialPort.Baud4800)
self.baudrate_comboBox.addItem("9600", QtSerialPort.QSerialPort.Baud9600)
self.serial = QtSerialPort.QSerialPort(
self,
readyRead=self.receive
)
@QtCore.pyqtSlot()
def receive(self):
while self.serial.canReadLine():
text = self.serial.readLine().data().decode()
text = text.rstrip('\r\n')
self.light_lineEdit.setText(text)
print(text)
@QtCore.pyqtSlot()
def send(self):
self.serial.write(self.lcd_lineEdit.text().encode())
@QtCore.pyqtSlot()
def connectToPort(self):
self.serial.setPortName(self.portname_comboBox.currentText()) # <---
self.serial.setBaudRate(self.baudrate_comboBox.currentData()) # <---
self.serial.open(QtCore.QIODevice.ReadWrite)
@QtCore.pyqtSlot(bool)
def disconnectFromPort(self):
self.serial.close()
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Upvotes: 2