【问题标题】:Introduce a text in a lineEdit of PyQt from a thread从线程中在 PyQt 的 lineEdit 中引入文本
【发布时间】:2014-08-07 14:38:08
【问题描述】:

如何在不折叠程序的情况下从获取数据的线程中的 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()

【问题讨论】:

  • 您的代码不能独立运行。使得检查它在做什么以及你想要什么变得更加困难。你能把这个例子写得更短更独立吗?

标签: python multithreading pyqt


【解决方案1】:

您可以使用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 类中的 slot 函数即可:

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)

【讨论】:

  • OP 使用的是 Python 线程,而不是 Qt 线程,因此您不能像建议的那样使用信号。
  • @three_pineapples 我没有在线程中使用信号。但是,他们的文档确实说:'Connections may be made across threads.'。不幸的是,目前尚不清楚这是否仅意味着 Qt 线程或 Python 基础线程。
  • 据我所知,信号只能附加到 QObjects,所以这意味着 QThreads 而已。
【解决方案2】:

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

第一种是使用 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 才能使其工作!

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    相关资源
    最近更新 更多