Чтобы изменение было заметным для пользователя, оно не может быть настолько быстрым, поскольку зрение медленное, идея состоит в том, чтобы дать заметное время, например, 500 мс. С другой стороны, цикл должен выполняться в другом потоке, чтобы не блокировать графический интерфейс и не связываться с ним через сигналы.
Учитывая вышеизложенное, решение является следующим:
import random
import threading
import time
import simpy
from PyQt5 import QtCore, QtWidgets, uic
def car_parking(env, name, ps, depart_time, parking_duration, manager):
yield env.timeout(depart_time)
print("Car %d arrived on station at %d" % (name, env.now))
manager.valueChanged.emit(name)
manager.entered.emit()
time.sleep(0.3)
with ps.request() as rq:
yield rq
time.sleep(0.3)
print("%d parked at %s" % (name, env.now))
yield env.timeout(parking_duration)
time.sleep(0.30)
print("%d leaving the Parking Station at %s" % (name, env.now))
manager.exited.emit()
def loop(number_of_cars, manager):
env = simpy.Environment()
ps = simpy.Resource(env, capacity=5)
for i in range(number_of_cars):
t = random.randint(1, 5)
env.process(car_parking(env, i, ps, i * 2, t, manager))
time.sleep(0.3)
print("The parking duration of Car %d is %d" % (i, t))
env.run()
class Manager(QtCore.QObject):
entered = QtCore.pyqtSignal()
exited = QtCore.pyqtSignal()
valueChanged = QtCore.pyqtSignal(int)
def start(self, number_of_cars):
threading.Thread(target=loop, args=(number_of_cars, self), daemon=True).start()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
uic.loadUi("design.ui", self)
self.manager = Manager()
self.manager.valueChanged.connect(self.parkedCars.display)
self.manager.entered.connect(self.on_entered)
self.manager.exited.connect(self.on_exited)
self.visualize.clicked.connect(self.on_clicked)
@QtCore.pyqtSlot()
def on_clicked(self):
try:
n = int(self.nCars.text())
self.manager.start(n)
except ValueError:
print("It must be an integer")
@QtCore.pyqtSlot()
def on_entered(self):
self.lEnter.setStyleSheet("color: green")
QtCore.QTimer.singleShot(500, lambda: self.lEnter.setStyleSheet("color: black"))
@QtCore.pyqtSlot()
def on_exited(self):
self.lExit.setStyleSheet("color: red")
QtCore.QTimer.singleShot(500, lambda: self.lExit.setStyleSheet("color: black"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())