Python Pyqt:从按钮更改图标
我刚开始使用pyqt,我想更改按钮的图标。 但我是从另一个班来的,pyqt不喜欢这样 错误是:QPixmap:在GUI线程之外使用pixmap是不安全的 我知道我必须使用信号发射。 但我不知道如何使用它来更改按钮的图标 这是我现在的代码: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
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行时,它们的确切输出是什么?