1

I am new to python and I am trying to learn simpy and pyqt5. I am making some program in which I want to change the label color at every iteration but I dont know why It shows only 1 color.

To change the color first i mention green color then black but after starting program it only shows black. Is there any way to change the color continuously.

def carParking(env, name, ps, depart_time, parking_Duration):
    yield env.timeout(depart_time)
    print("Car %d arrived on station at %d" % (name, env.now))
    app.processEvents()
    dlg.parkedCars.display(name)
    app.processEvents()
    dlg.lEnter.setStyleSheet('color: Green')
    dlg.lEnter.setStyleSheet('color: Black')
    dlg.lEnter.setStyleSheet('color: Green')
    time.sleep(0.30)
    with ps.request() as req:
        yield req
        time.sleep(0.30)
        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))
        dlg.lExit.setStyleSheet('color: Red')

In above code You can see the color green black green but it doesnt work like that. It only shows only one color which is green. The remaining code is given below

env = simpy.Environment()
ps = simpy.Resource(env, capacity=5)

def syslot(self):
    #a=dlg.parkingSpace.setText(str(float(dlg.nCars.text())))
    ab=int(dlg.nCars.text())
    for i in range(ab):
        a = randint(1, 5)
       # dlg.lEnter.setStyleSheet('color: black')
       # dlg.lExit.setStyleSheet('color: black')
        env.process(carParking(env,  i, ps, i * 2, a))
        time.sleep(0.10)
        print("The parking duration of Car %d is %d" % (i, a))
        env.run()

app =QtWidgets.QApplication([])
dlg = uic.loadUi("design.ui")
dlg.visualize.clicked.connect(syslot)
dlg.show()
sys.exit(app.exec_())

Please tell me what should I do to change the label color continuously. Thank you in advance.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Although you have many errors, for example try to change the size of the window while the program is running you will see your window freeze, I see another error that you do not realize: our eyes are slow, so changes that last few us / ms we will not observe it, and in your case 3 consecutive commands will be in those units time, so the color change from green-black-green is not observed. What do you think about what I'm pointing to? – eyllanesc Oct 05 '19 at 05:41
  • @ eyllanesc thank you for your comment. could you please guide me in this regard. – M. Tayyab Ali Oct 05 '19 at 06:54
  • I have a question: the color change you want is G-B-G, how long should each color be displayed? – eyllanesc Oct 05 '19 at 06:57
  • for a time t. Actually this program is to visualize the car parking. so to visualize either car is entering in park or not i want to change the label color. For example. if the car enter it should turn into green and then come back to original color black. and if the car is leaving then it should turn in red and turn back to its default color, like this. – M. Tayyab Ali Oct 05 '19 at 07:01
  • The thing is to choose time. According to what you indicate, I understand that there are 2 important times T1: enter time and T2: leave time. In your program, which command line is equivalent to "enter time" and "leave time"? Also share the .ui – eyllanesc Oct 05 '19 at 07:08
  • Actually this is working on some loop iterations. In above program you can see carParking function in which the car is entering and leaving. In log file it is working perfectly but I want to add some visualization in that. thats why I decide to change the colors when the program reads the line.Here i uploaded the file[Link] (https://drive.google.com/open?id=1iAPSa3wxvpEJ-JhKl4JHpJkL0PiZDBf9) [Link2] (https://drive.google.com/open?id=1G-b9YTAhdaVVRR5Bb6RD9OM9Z-4HwAte) – M. Tayyab Ali Oct 05 '19 at 07:35
  • 1) You have not answered my question. 2) Apparently it works but it is not robust, for example put 100 in "nCars" and press the button "visualize", then try to change the size of the window, if you do you will see something unpleasant. So your program is not correct. It would be great if you answered what I asked you. – eyllanesc Oct 05 '19 at 07:40
  • I dont know how to change the size of window, I just add some labels and QLCD in which I will see how many cars are in parking area and for this I wiil try to handle the number of iterations but to handeling the colors i dont know how to do that.if you have some suggestion it could be great because I am new to this and all i have is just imagination anyway – M. Tayyab Ali Oct 05 '19 at 08:00
  • You say: *I dont know how to change the size of window*, mmm, use the mouse to change the size of the window. – eyllanesc Oct 05 '19 at 08:04
  • Thank you for guidance, could you please help me in my problem. it could be very helpful sir. – M. Tayyab Ali Oct 05 '19 at 08:07
  • see my solution.. – eyllanesc Oct 05 '19 at 08:53

1 Answers1

1

So that the change is appreciable by the user, it cannot be so fast since the sense of sight is slow, the idea is to give an appreciable time, for example 500 ms. On the other hand, a loop must be executed in another thread so as not to block the GUI and communicate with the GUI via the signals.

Considering the above, the solution is:

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_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • but it doesn't synchronized with print statements. it is not working like that if the car enter green will blink and when car leaves red will blink, like this . in this case both sides are blinking without synchronizing with print statements – M. Tayyab Ali Oct 06 '19 at 05:17
  • @Tayyab You seem to not understand how the different elements of the application interact. 1) If you realize I make the color change for 500 ms, and in the real world it works because the exit of a car takes longer than that time, but in your emulation you use 300ms which is very little. 2) The console and the GUI are 2 separate processes, each with its own life cycle, so don't expect perfect synchronization. – eyllanesc Oct 06 '19 at 05:22