在Qt Thread Python中更改按钮颜色

时间:2017-05-04 17:15:09

标签: python multithreading pyqt pyqt4

我需要更改QPushButton的颜色,但发生错误:“AttributeError:type object'ProyectoTFM'没有属性'ui'”。 我不知道从我的线程中获取ui变量。 这是我的代码:

import sys
import OpenOPC
import time
import threading

from proyectoQt import *


def actualizarDatosOPC():
    while 1:
        time.sleep(5)
        if(itemsOPC[15])[1]!=0:
            #Error on next line
            ProyectoTFM.ui.AP08Button.setStyleSheet("background-color: red")
    return


class ProyectoTFM(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.startTheThread()
        print('Init')

    def startTheThread(self):
        threadQt = threading.Thread(target = actualizarDatosOPC)
        threadQt.start()


def clienteOPC():
    opc=OpenOPC.client()
    opc.connect('Kepware.KEPServerEX.V6')

    global itemsOPC

    while 1:
        itemsOPC = opc.read(opc.list('PLC.PLC.TAGS'))
        time.sleep(5)
    return

threads = list()
threadOPC = threading.Thread(target=clienteOPC)
threads.append(threadOPC)
threadOPC.start()
time.sleep(5)


if __name__== "__main__":
    app=QtGui.QApplication(sys.argv)
    myapp = ProyectoTFM()
    myapp.show()
    sys.exit(app.exec_())
    threadOPC.__delete()

对不起我的英文,谢谢。

3 个答案:

答案 0 :(得分:0)

一些事情:

  1. 您实际上从未将UI传递给函数actualizarDatosOPC 所以它不知道它存在。
  2. 您有什么理由不能使用PyQt内置的线程工具吗?如果您打算使用PyQt,那么购买整个框架可能是有意义的。

    def startTheThread(self):
        self.threadQt = QThread()
        d = actualizarDatosOPC(self)
        d.moveToThread(self.threadQt) 
        self.threadQt.start()
    
    def actualizarDatosOPC(widget):
        .... widget.AP08Button.setStyleSheet("background-color: red")
    
  3. 如果你确实选择了这条路线,我会看看这个有一个好例子的线程: How to use QThread correctly in pyqt with moveToThread()?

    此外,虽然初始化Window的方式有效,但这是更标准的方法:

    class ProyectoTFM(QMainWindow, Ui_MainWindow):
        def __init__(self, parent):
            # General Init Stuff
            super(Login, self).__init__(parent)
            self.setupUi(self)
    

    之后,每当你想要在UI中引用某些内容时,你需要做的就是参考self ._____。例如,如果您有一个名为buttonA的按钮,则self.buttonA将是适当的引用。

    修改 正如另一个答案中所提到的,实际更改按钮颜色的正确方法是向主线程发出一个触发器,然后通过更改按钮颜色来响应。

答案 1 :(得分:0)

即使你让它工作,你can't modify the UI from a thread directly

答案 2 :(得分:0)

将视图从不同的线程修改为主视图是不正确的,在不使用QThread的情况下解决问题的方法是创建连接到某个插槽的信号,该插槽改变按钮的颜色。为了能够从新线程发出信号,我们必须通过参数args将对象传递给他。

def actualizarDatosOPC(obj):
    while 1:
        time.sleep(5)
        if(itemsOPC[15])[1]!=0:
            #Error on next line
            obj.sendChangeColor.emit()
    return


class ProyectoTFM(QtGui.QMainWindow):
    sendChangeColor = QtCore.pyqtSignal()
    def __init__(self,parent=None):
        QtGui.QMainWindow.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.startTheThread()
        print('Init')
        self.sendChangeColor.connect(lambda: self.ui.AP08Button.setStyleSheet("background-color: red"))

    def startTheThread(self):
        threadQt = threading.Thread(target = actualizarDatosOPC, args=(self,))
        threadQt.start()