Причина, по которой графический интерфейс не обновляется потоком, заключается в том, что Qt запрещает обновление графических элементов из другого потока, для получения дополнительной информации читайте Поток графического интерфейса и рабочий поток .Поток не должен использоваться, если задача не тяжелая, например, если мы тестируем, когда он потребляет изменение цвета, используя следующий код:
t = QtCore.QElapsedTimer()
t.start()
pal = QtGui.QPalette([QtCore.Qt.red, QtCore.Qt.blue, QtCore.Qt.green][self._color])
for x in range(self.grid.rowCount()):
for y in range(self.grid.columnCount()):
w = self.grid.itemAtPosition(x, y).widget()
if w is not None:
w.setPalette(pal)
self._color = (self._color +1) % 3
print(t.elapsed(), " milliseconds")
Получение следующих результатов:
4 milliseconds
2 milliseconds
2 milliseconds
3 milliseconds
2 milliseconds
3 milliseconds
3 milliseconds
2 milliseconds
3 milliseconds
# ...
Поддерживая мое утверждение, что это не тяжелая задача, поэтому в этом случае вам следует использовать QTimer, который позволяет вам выполнять периодические задачи:
from PyQt5 import QtCore, QtGui, QtWidgets
class EmulatorWindow(QtWidgets.QMainWindow):
def __init__(self, spacing=1, screen_resolution=(16, 16)):
super().__init__()
self.spacing = spacing
# Pixel Grid
self.grid = QtWidgets.QGridLayout()
self.grid.setContentsMargins(0, 0, 0, 0)
self.grid.setSpacing(self.spacing)
for x in range(screen_resolution[0]):
for y in range(screen_resolution[1]):
pixel = QtWidgets.QWidget(autoFillBackground=True)
self.grid.addWidget(pixel, y, x)
# Window Properties
self.setGeometry(300, 300, 450, 495)
self.setWindowTitle('Pixels Grid')
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
widget.setLayout(self.grid)
self.setMinimumSize(QtCore.QSize(450, 495))
self._color = 0
timer = QtCore.QTimer(self, interval=1000/30, timeout=self.applicationRunner)
timer.start()
@QtCore.pyqtSlot()
def applicationRunner(self):
pal = QtGui.QPalette([QtCore.Qt.red, QtCore.Qt.blue, QtCore.Qt.green][self._color])
for x in range(self.grid.rowCount()):
for y in range(self.grid.columnCount()):
w = self.grid.itemAtPosition(x, y).widget()
if w is not None:
w.setPalette(pal)
self._color = (self._color +1) % 3
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = EmulatorWindow()
ex.show()
sys.exit(app.exec_())