【问题标题】:Change Button Color in Qt Thread Python在 Qt Thread Python 中更改按钮颜色
【发布时间】:2017-10-02 23:57:55
【问题描述】:

我需要更改 QPushButton 的颜色,但出现错误:“AttributeError: type object 'ProyectoTFM' has no attribute '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


    【解决方案1】:

    一些事情:

    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 将是适当的引用。

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        将视图从不同的线程修改为主线程是不正确的,不使用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()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-03
          • 2014-07-11
          相关资源
          最近更新 更多