Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pyqt:从按钮更改图标_Python_Pyqt - Fatal编程技术网

Python Pyqt:从按钮更改图标

Python Pyqt:从按钮更改图标,python,pyqt,Python,Pyqt,我刚开始使用pyqt,我想更改按钮的图标。 但我是从另一个班来的,pyqt不喜欢这样 错误是:QPixmap:在GUI线程之外使用pixmap是不安全的 我知道我必须使用信号发射。 但我不知道如何使用它来更改按钮的图标 这是我现在的代码: import sys import time from PyQt4 import QtGui, QtCore from pymodbus.exceptions import ConnectionException from sqlalchemy.orm imp

我刚开始使用pyqt,我想更改按钮的图标。 但我是从另一个班来的,pyqt不喜欢这样

错误是:QPixmap:在GUI线程之外使用pixmap是不安全的

我知道我必须使用信号发射。 但我不知道如何使用它来更改按钮的图标

这是我现在的代码:

import sys
import time
from PyQt4 import QtGui, QtCore
from pymodbus.exceptions import ConnectionException
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from data.database import Tags, Query_Tags


class Example(QtGui.QMainWindow):

    def __init__(self):
        super(Example, self).__init__()

        self.db_engine = create_engine('mysql://modbususer:modbususer@localhost/modbus')

        self.db_session = sessionmaker(bind=self.db_engine)
        self.db_session = self.db_session()  

        self.status = 0
        self.initUI()

    def initUI(self):               

        self.button = QtGui.QPushButton('Aan', self)
        self.button.clicked.connect(self.run)     
        self.button.move(50,50)


        Uit = QtGui.QPushButton('Uit', self)
        Uit.clicked.connect(self.off)     
        Uit.move(150,50)

        self.setGeometry(300, 300, 500, 150)
        self.setWindowTitle('Quit button')    
        self.show()

        self.worker = WorkThread(self)
        self.worker.start()

    def run(self):

        add_tag = Query_Tags('18', '1')
        self.db_session.add(add_tag)
        self.db_session.commit()


    def off(self):

        add_tag = Query_Tags('18', '0')
        self.db_session.add(add_tag)
        self.db_session.commit()

        self.status = 0

        print self.store

    def change(self):

        print "test"
        #self.button.setIcon(QtGui.QIcon("/home/stijnb/test/icon.png"))
        #self.button.setIconSize(QtCore.QSize(16,16))

    def database(self, store):

        self.store = store

"""
    Thread
"""
class WorkThread(QtCore.QThread):

    def __init__(self, layout):

        QtCore.QThread.__init__(self)

        self.layout = layout

    def __del__(self):
        self.wait()

    def run(self):

        self.database = {}

        while True:

            self.db_engine = create_engine('mysql://modbususer:modbususer@localhost/modbus')

            self.db_session = sessionmaker(bind=self.db_engine)
            self.db_session = self.db_session() 

            for result in self.db_session.query(Tags):

                self.database[int(result.id)] = {'naam': result.name, 'value': result.value}

            self.change_icons()
            time.sleep(1)

        return 

        self.terminate()

    def change_icons(self):

        print self.database[21]['value']

        if self.database[21]['value'] == '1':

            self.layout.button.setIcon(QtGui.QIcon("/home/stijnb/test/aan.png"))
            self.layout.button.setIconSize(QtCore.QSize(16,16))

        else:

            self.layout.button.setIcon(QtGui.QIcon("/home/stijnb/test/uit.png"))
            self.layout.button.setIconSize(QtCore.QSize(16,16))

def main():

    app = QtGui.QApplication(sys.argv)

    ex = Example()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

除了主GUI线程之外,您不能从任何其他线程接触GUI元素。这就是Qt引入消息传递(信号和插槽)的原因。您可以连接到来自工作线程的信号,该信号将在主线程中捕获,然后在主线程中您可以更改所需的任何元素

这里是一个非常简单的示例,我在其中演示了这个概念

import sys
from PyQt4 import QtGui, QtCore

class Example(QtGui.QMainWindow):
    def __init__(self):
        super(Example, self).__init__()
        # Create a button and set it as a central widget
        self.button = QtGui.QPushButton('My Button', self)
        self.setCentralWidget(self.button)
        # Start the thread
        self.worker = WorkThread(self)
        self.worker.start()
        # Connect the thread's signal "change_text" to
        # "self.change_thread" function
        self.worker.change_text.connect(self.change_text)

    def change_text(self):
        # Slots are always executed in the GUI thread so it's safe to change
        # anything you want in a slot function. Here we just flip the button
        # text from foo to bar and back. But you can change the image or do
        # whatever you want.
        # Slots can also receive parameters so you can emit from your thread
        # which text should be set
        self.button.setText('bar' if self.button.text() == 'foo' else 'foo')


class WorkThread(QtCore.QThread):
    # Define the signal
    change_text = QtCore.pyqtSignal()

    def __init__(self, layout):
        QtCore.QThread.__init__(self)

    def run(self):
        while True:
            # emit the signal every 3 seconds
            self.sleep(3)
            self.change_text.emit()


app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec_())

@Stijnb你试过和我发布的完全相同的代码吗?如果是,您使用的是哪个版本的PyQt4?我已在本周安装。我想我有最新的版本。你能在Python解释器中键入:
从PyQt4导入QtCore
,然后
打印QtCore.Signal
,最后
打印QtCore.\uuuuuuuu版本
并将结果粘贴到这里吗。这真是一个奇怪的错误。这是python解释器的结果:>>>从PyQt4导入QtCore>>>打印QtCore.Signal Traceback(最近一次调用):文件“”,第1行,在AttributeError:'module'对象没有属性'Signal'>>打印QtCore.\uu version\uuuuu Traceback(最近一次调用):文件“”,第1行,在AttributeError中:“模块”对象没有属性“版本”>>>打印QtCore.\uuuuu版本\uuuuuuuuu回溯(最近一次调用):文件“”,第1行,在AttributeError中:“模块”对象没有属性“版本”确定,但当您在终端中键入所有3行时,它们的确切输出是什么?