如何从周围的代码引用PyQt UI元素



假设我有一个带有三个控件的简单窗口:一个组合框、一个push(切换)按钮和一个文本编辑控件。为了增加趣味,我需要在线程中运行算法(当按下切换键时),但我想解决主要问题的方法不会受到

的影响。

当切换按钮被按下时,我想读取当前的ComboBox值并更新TextEdit的值。

这是我尝试过的方法,但没有成功。也许这是一个愚蠢的错误,或者我应该改变设计(QML会帮助使这更容易一点吗?):

#!/usr/bin/env python
import sys
import threading
try:
    from PySide import QtGui
    from PySide import QtCore
except:
    from PyQt4.QtCore import pyqtSlot as Slot
    from PyQt4 import QtGui
    from PyQt4 import QtCore

class MyUI(QtGui.QWidget):
    def __init__(self):
        super(MyUI, self).__init__()
        self.initUI()
    def initUI(self):
        someValues = [1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]
        self.setGeometry(100, 300, 640, 450) #window's geometry
        lblValueChoice = QtGui.QLabel(self)
        lblValueChoice.setGeometry(10, 10, (self.width() - 20), 27)
        lblValueChoice.setText("Select your value:")
        cmbValueChoice = QtGui.QComboBox(self)
        cmbValueChoice.setObjectName("valueChoice")
        cmbValueChoice.setGeometry(10, (lblValueChoice.y() + lblValueChoice.height() + 5), (self.width() - 20), 27)
        for item in someValues: cmbSerialPorts.addItem(item)
        cmbSerialPorts.setCurrentIndex(len(someValues)-1)
        pbStartReading = QtGui.QPushButton("Start doing the magic!", self)
        pbStartReading.setGeometry(10, (cmbValueChoice.y() + cmbValueChoice.height() + 10), (self.width() - 20), 27)
        pbStartReading.setCheckable(True)
        pbStartReading.clicked[bool].connect(lambda: self.startReading(bool, str(cmbValueChoice.currentText())))
        textEdit = QtGui.QTextEdit(self)
        textEdit.setObjectName("textEdit")
        textEdit.setGeometry(10, (pbStartReading.y() + pbStartReading.height() + 10), (self.width() - 20), (self.height() - (pbStartReading.y() + pbStartReading.height() + 10) - 10) )
        textEdit.append(add_env())
        self.setWindowTitle(u'MyMiserableUIFailure')
        self.show()
    def startReading(self, bool, myvalue):
        threading.Thread(target=self.readingLoop, args=(bool, myvalue, )).start()
    def readingLoop(self, bool, myvalue):
        while bool:
            # the error happens in the line below, when I
            # try to reference the textEdit control
            # -------------------------------------------
            textEdit.append("this actually works!n")

def main():
    app = QtGui.QApplication(sys.argv)
    theui = MyUI()
    sys.exit(app.exec_())
def add_env():
    newLine = QtCore.QString("n")
    env_info = "The system is:" + newLine
    env_info += newLine + "System/OS name:            " + str(platform.system())
    env_info += newLine + "System release:          " + str(platform.release())
    env_info += newLine + "System release version:  " + str(platform.version())
    env_info += newLine + "Machine type:              " + str(platform.machine())
    env_info += newLine + "Platform:                  " + str(platform.platform(aliased=0, terse=1))
    env_info += newLine + "Processor:                 " + str(platform.processor())
    env_info += newLine + "Network name:              " + str(platform.node())
    env_info += newLine + "Python ver(maj,min,patch): " + str(platform.python_version_tuple())
    env_info += newLine + "Python build:              " + str(platform.python_build())
    env_info += newLine + "Python implementation:     " + str(platform.python_implementation())
    env_info += newLine
    env_info += newLine + "***************************"
    return env_info
if __name__ == '__main__':
    main()

你不能直接引用来自其他线程的ui元素。你应该使用信号。我在你的代码中改变了它,见下面。我没有测试它,但这是应该这样做的。

#!/usr/bin/env python
import sys
import threading
try:
    from PySide import QtGui
    from PySide import QtCore
    from PySide.QtCore import Signal
except:
    from PyQt4.QtCore import pyqtSignal as Signal
    from PyQt4 import QtGui
    from PyQt4 import QtCore

class MyUI(QtGui.QWidget):
# Add Signal
    text_edit_evt = Signal(str)
    def __init__(self):
        super(MyUI, self).__init__()
        self.initUI()
# Connect the signal
        self.text_edit_evt.connect(self.textEdit.append)
    def initUI(self):
        someValues = [1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]
        self.setGeometry(100, 300, 640, 450) #window's geometry
        lblValueChoice = QtGui.QLabel(self)
        lblValueChoice.setGeometry(10, 10, (self.width() - 20), 27)
        lblValueChoice.setText("Select your value:")
        cmbValueChoice = QtGui.QComboBox(self)
        cmbValueChoice.setObjectName("valueChoice")
        cmbValueChoice.setGeometry(10, (lblValueChoice.y() + lblValueChoice.height() + 5), (self.width() - 20), 27)
        for item in someValues: cmbSerialPorts.addItem(item)
        cmbSerialPorts.setCurrentIndex(len(someValues)-1)
        pbStartReading = QtGui.QPushButton("Start doing the magic!", self)
        pbStartReading.setGeometry(10, (cmbValueChoice.y() + cmbValueChoice.height() + 10), (self.width() - 20), 27)
        pbStartReading.setCheckable(True)
        pbStartReading.clicked[bool].connect(lambda: self.startReading(bool, str(cmbValueChoice.currentText())))
# Use self.textEdit so it can be referenced from other functions
        self.textEdit = QtGui.QTextEdit(self)
        self.textEdit.setObjectName("textEdit")
        self.textEdit.setGeometry(10, (pbStartReading.y() + pbStartReading.height() + 10), (self.width() - 20), (self.height() - (pbStartReading.y() + pbStartReading.height() + 10) - 10) )
        self.textEdit.append(add_env())
        self.setWindowTitle(u'MyMiserableUIFailure')
        self.show()
    def startReading(self, bool, myvalue):
        threading.Thread(target=self.readingLoop, args=(bool, myvalue, )).start()
    def readingLoop(self, bool, myvalue):
        while bool:
            # the error happens in the line below, when I
            # try to reference the textEdit control
            # -------------------------------------------
# Emit the Signal we created
            self.text_edit_evt.emit("this actually works!n")

def main():
    app = QtGui.QApplication(sys.argv)
    theui = MyUI()
    sys.exit(app.exec_())
def add_env():
    newLine = QtCore.QString("n")
    env_info = "The system is:" + newLine
    env_info += newLine + "System/OS name:            " + str(platform.system())
    env_info += newLine + "System release:          " + str(platform.release())
    env_info += newLine + "System release version:  " + str(platform.version())
    env_info += newLine + "Machine type:              " + str(platform.machine())
    env_info += newLine + "Platform:                  " + str(platform.platform(aliased=0, terse=1))
    env_info += newLine + "Processor:                 " + str(platform.processor())
    env_info += newLine + "Network name:              " + str(platform.node())
    env_info += newLine + "Python ver(maj,min,patch): " + str(platform.python_version_tuple())
    env_info += newLine + "Python build:              " + str(platform.python_build())
    env_info += newLine + "Python implementation:     " + str(platform.python_implementation())
    env_info += newLine
    env_info += newLine + "***************************"
    return env_info
if __name__ == '__main__':
    main()

最新更新