我正在尝试在操作过程中更改按钮的样式。
当按下按钮时,我想让它们变成蓝色,然后读取 rfid 卡,然后通过 ID 将按钮的颜色更改为绿色或红色(在代码中只是红色以使其更容易)。
问题是,将按钮样式更改为蓝色没有任何作用(绿色和红色效果很好)。 它正在等待完成“clicked()”方法吗? 如何告诉 PyQt5“现在就做!” ?
编辑:我将伪代码修改为可重现的示例。
#!/usr/bin/python3
import sys
import time
from PyQt5.QtWidgets import *
class MainScreen(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton("TEXT")
self.button.clicked.connect(self.clicked)
self.changeButtonColor("black") # set default style
self.grid = QGridLayout(self)
self.grid.addWidget(self.button)
self.show()
def changeButtonColor(self, color):
self.button.setStyleSheet("QPushButton{ \
color: "+color+"; font: bold 18px;}")
def clicked(self):
self.changeButtonColor("blue") # nothing happening (this is my problem!)
uid = self.readCard() # reading ID from rfid card
self.changeButtonColor("red")
def readCard(self):
#return rfid.read() # in real case
time.sleep(2)
return "12345678"
def main():
app = QApplication(sys.argv)
window = MainScreen()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
最佳答案
void QTimer::singleShot(int msec, const QObject *receiver, const char *member)
This static function calls a slot after a given time interval.
It is very convenient to use this function because you do not need to bother with a timerEvent or create a local QTimer object.
import sys
import time
from PyQt5.QtWidgets import *
from PyQt5 import QtCore
class MainScreen(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton("TEXT")
self.button.clicked.connect(self.clicked)
self.changeButtonColor("black")
self.grid = QGridLayout(self)
self.grid.addWidget(self.button)
self.show()
def changeButtonColor(self, color):
self.button.setStyleSheet("QPushButton{ \
color: "+color+"; font: bold 18px;}")
def clicked(self):
self.changeButtonColor("blue") # nothing happening (this is my problem!)
# time.sleep(2) # reading ID from rfid card
# self.changeButtonColor("red")
QtCore.QTimer.singleShot(2000, lambda: self.changeButtonColor("red")) # <---
def main():
app = QApplication(sys.argv)
window = MainScreen()
sys.exit(app.exec_())
<小时/>
更新
import sys
import time
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
class Worker(QtCore.QObject): # +++
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
data = QtCore.pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.running = False
self.stop = 5
@QtCore.pyqtSlot()
def read_data_from_sensor(self):
self.started.emit()
time.sleep(1) # We simulate the blocking process
while self.running and self.stop:
dt = time.strftime("%Y-%m-%d %H:%M:%S")
self.data.emit(dt)
time.sleep(1) # We simulate the blocking process
self.stop -= 1
self.finished.emit()
class MainScreen(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton("TEXT Start")
self.button.clicked.connect(self.clicked)
self.changeButtonColor("black")
self.label_data = QtWidgets.QLabel(self, alignment=QtCore.Qt.AlignCenter)
self.label_data.setText('Pending')
self.grid = QGridLayout(self)
self.grid.addWidget(self.label_data)
self.grid.addWidget(self.button)
self.show()
### vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self._worker = Worker()
self._worker.started.connect(self.on_started)
self._worker.finished.connect(self.on_finished)
self._worker.data.connect(self.update_label)
self._thread = QtCore.QThread(self)
self._thread.start()
self._worker.moveToThread(self._thread)
@QtCore.pyqtSlot()
def on_started(self):
self.label_data.setText("Start to read")
self.button.setText("TEXT Stop")
self.button.setEnabled(True)
self._worker.stop = 5
@QtCore.pyqtSlot()
def on_finished(self):
self.label_data.setText("Pending")
self.button.setText("TEXT Start")
self.button.setEnabled(True)
self.changeButtonColor("red") # <---
self._worker.running = False
self._worker.stop = 5
@QtCore.pyqtSlot(str)
def update_label(self, data):
self.label_data.setText(data)
### ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def changeButtonColor(self, color):
self.button.setStyleSheet("QPushButton{ \
color: "+color+"; font: bold 18px;}")
def clicked(self):
self.changeButtonColor("blue") # nothing happening (this is my problem!)
# time.sleep(2) # reading ID from rfid card
# self.changeButtonColor("red")
# QtCore.QTimer.singleShot(2000, lambda: self.changeButtonColor("red")) # <---
### vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
if self._worker.running:
self._worker.running = False
else:
self._worker.running = True
QtCore.QTimer.singleShot(0, self._worker.read_data_from_sensor)
self.button.setEnabled(False)
### ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def main():
app = QApplication(sys.argv)
window = MainScreen()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
关于python - 事件期间GUI没有变化吗? (Python3.6、PyQt5),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57852863/