在Qt Thread Python中更改按钮颜色

问题描述 投票:1回答:3

我需要更改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()

对不起,我的英文和谢谢。

python multithreading pyqt pyqt4
3个回答
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()

0
投票

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


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

如果你确实选择了这条路线,我会看看这个有一个好例子的线程: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将是相应的引用。

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

© www.soinside.com 2019 - 2024. All rights reserved.