Search code examples
pythonpython-3.xarduinogtkgtk3

In Python, how to append text from Arduino in a GtkTextview when connecting to a port?


I am using the following code:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import serial
import serial.tools.list_ports

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk

class SerialComm(Gtk.Window):

glade = "serial_comm.glade"

builder = Gtk.Builder.new_from_file(glade)
builder.add_from_file(glade)

comboPorts = builder.get_object("comboPorts")
comboBauds = builder.get_object("comboBauds")
btn_conectar = builder.get_object("btnConectar")

textbuffer = builder.get_object("textbuffer")
textview = builder.get_object("textview")

def get_ports(self):
    ports = list(serial.tools.list_ports.comports())

    for p in ports:
        self.comboPorts.append_text(p[0])
        self.comboPorts.set_active(1)
        print(p[0])

try open a port and get arduino data

def open_port(self, widget):
    port = self.comboPorts.get_active_text()
    baud = self.comboBauds.get_active_text()
    arduino = serial.Serial(port, baud)
    temp = arduino.readline()

    self.textbuffer.set_text(temp)
    self.textview.set_buffer(self.textbuffer)
    arduino.close()

def __init__(self):
    window = self.builder.get_object("window")
    window.connect("destroy", Gtk.main_quit)

    self.btn_conectar.connect("clicked", self.open_port)

    self.get_ports()

    window.show_all()

if __name__ == '__main__':
application = SerialComm()
Gtk.main()

But I have to click on a button to get the data (temperature of a sensor, read every second).

self.btn_open.connect("clicked", self.openport)

How to update textview content automatically, after clicking the button?


Solution

  • A better way would be to open the port and read from it as the information comes in. Example:

    from gi.repository import GLib #include this import with the rest of your imports
    
    def open_port(self, widget):
        port = self.comboPorts.get_active_text()
        baud = self.comboBauds.get_active_text()
        self.textview.set_buffer(self.textbuffer)
        arduino = serial.Serial(port, baud)
        GLib.timeout_add_seconds(1, self.read_info, arduino)
    
    def read_info (self, arduino)
        temp = arduino.readline()    
        self.textbuffer.set_text(temp)
        return True