1

How can I introduce a text in a lineEdit from a thread that are getting the data whithout colapse the program? The important line is in the class "fil" where it shows Principal.self.aplicacio.actual_lineEdit.setText(self.temp)

    # !/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import serial
import threading
from time import sleep
from PyQt4 import QtCore, QtGui
from temperaturaUI import Ui_Form


class Principal(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)

        self.aplicacio = Ui_Form()
        self.aplicacio.setupUi(self)

        self.aplicacio.sortir_Button.clicked.connect(exit)

        self.aplicacio.connectar_Button.clicked.connect(self.connectar)

    def connectar(self):
        try:
            arduino = serial.Serial('/dev/ttyACM0', 9600)
            print "Connectat amb èxit"
            temperatura = fil(0, arduino, self.aplicacio.actual_lineEdit)
            temperatura.start()
        except:
            print "Impossible connectar a l'Arduino"


class fil(threading.Thread):
    def __init__(self, temp, serie, line):
        threading.Thread.__init__(self)
        self.temp = temp
        self.serie = serie
        self.line = line

    def run(self):
        try:
            while 1:
                self.temp = self.serie.readline()
                if self.temp != 0:
                     **Principal.self.aplicacio.actual_lineEdit.setText(self.temp)**
                sleep(0.2)
        except:
            print "Error al llegir de l'Arduino"



def main():
    app = QtGui.QApplication(sys.argv)
    aplicacio = Principal()
    aplicacio.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
user3748883
  • 319
  • 2
  • 16

2 Answers2

0

You can use signals. You would add a signal to the fil class that emits the new text:

class fil(threading.Thread):
    update_line_edit = pyqtSignal(str)
    def __init__(self, temp, serie, line):
        ...

    def run(self):
        try:
            while True:
                self.temp = self.serie.readline()
                if not self.temp:
                    update_line_edit.emit(self.temp)
        ...

Then, simply connect that signal to a slot function in your Principal class:

class Principal(QtGui.QWidget):
    def __init__(self):
        ...

    def connectar(self):
        try:
            arduino = serial.Serial('/dev/ttyACM0', 9600)
            print "Connectat amb èxit"
            temperatura = fil(0, arduino, self.aplicacio.actual_lineEdit)
            temperatura.change_line_edit.connect(self.update_line_edit)
        ...

    def update_line_edit(self, text):
        self.aplicacio.actual_lineEdit.setText(text)
BeetDemGuise
  • 954
  • 7
  • 11
  • The OP is using Python threads, not Qt threads, so you can't use signals like you have suggested. – three_pineapples Jun 17 '14 at 21:49
  • @three_pineapples I haven't used signals in threads. However, their documentation does say: ['Connections may be made across threads.'](http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html#new-style-signal-and-slot-support). Unfortunately, it is unclear whether this means only Qt threads or Python base threads. – BeetDemGuise Jun 18 '14 at 12:03
  • As far as I'm aware, signals can only be attached to QObjects so it means QThreads only. – three_pineapples Jun 21 '14 at 01:53
0

There are a few ways to do this correctly.

The first is to use a QThread instead of a python thread. You can then use Qt signals to pass a message back from the fil thread to the Qt MainThread and append the message to the QLineEdit there. Another similar approach is to continue using a Python thread, but place your message in a Python Queue.Queue() object. This Queue is then read by a secondary QThread, whose sole purpose is to read messages out of the Queue and emit a signal back to the MainThread.

The common feature of these two methods is that you only access Qt GUI objects from the MainThread and use signals/slots to communicate between threads. Here are some other questions where I've answered similar questions (you should be able to adapt them to your program):

However, since answering those questions, my colleagues and I have created a project that helps simplify writing multi-threaded Qt applications. The project is called qtutils and is on PyPi so it can be installed with pip or easy_install (just run pip install qtutils or easy_install qtutils from a commandline/terminal window).

This library has (among others) some functions inmain and inmain_later which will run a specified method in the Qt MainThread (regardless of the thread the call is made from) synchronously or asynchronously. Documentation on how to use these methods is here. I've modified your example code to use my inmain method and put the code here: http://pastebin.com/QM1Y6zBx -- obviously you need to install qtutils for it to work!

Community
  • 1
  • 1
three_pineapples
  • 11,579
  • 5
  • 38
  • 75