从线程中引入PyQt的lineEdit中的文本

时间:2014-06-17 14:19:42

标签: python multithreading pyqt

如何从一个线程中引入一个lineEdit中的文本,这个线程可以获取数据而不会使程序崩溃?重要的一行是在“fil”类中,它显示了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()

2 个答案:

答案 0 :(得分:0)

您可以使用signals。您可以向发出新文本的fil类添加信号:

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)
        ...

然后,只需将该信号连接到slot类中的Principal函数:

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)

答案 1 :(得分:0)

有几种方法可以正确地执行此操作。

第一种是使用QThread而不是python线程。然后,您可以使用Qt信号将消息从fil线程传递回Qt MainThread,并将消息附加到QLineEdit。另一种类似的方法是继续使用Python线程,但将消息放在Python Queue.Queue()对象中。然后,这个Queue由辅助QThread读取,其唯一目的是从Queue读取消息并向MainThread发回信号。

这两种方法的共同特点是您只能从MainThread访问Qt GUI对象,并使用信号/槽来在线程之间进行通信。以下是我回答类似问题的其他问题(您应该能够根据自己的计划进行调整):

然而,自从回答这些问题后,我和我的同事创建了一个项目,帮助简化编写多线程Qt应用程序。该项目名为 qtutils ,位于PyPi,因此可以使用pip或easy_install进行安装(只需从命令行运行pip install qtutilseasy_install qtutils /终端窗口)。

这个库有(以及其他)一些函数inmaininmain_later,它们将同步或异步地在Qt MainThread中运行指定的方法(无论调用的是什么线程)。有关如何使用这些方法的文档是here。我已修改您的示例代码以使用我的inmain方法并将代码放在此处:http://pastebin.com/QM1Y6zBx - 显然您需要安装 qtutils 才能使其正常工作!