【问题标题】:SimPy and PyQt InteractionSimPy 和 PyQt 交互
【发布时间】:2021-09-15 14:52:48
【问题描述】:

我一直在寻求让 PyQt 和 SimPy 相互“交谈”。例如,在下面的代码中,我有一个带有单个标签的 PyQt 小部件,用于显示 SimPy 环境时间。我希望这个标签随着模拟的进行而更新(我试图用simpy_generator 函数来显示它——小部件中的标签被更新,SimPy 在一个时间单位内超时,并且这种模式重复)。

import sys
import simpy
from PyQt5 import QtWidgets

class Window(QtWidgets.QWidget):
    """ A generic Qt window that can interact with SimPy.
    """

    def __init__(self, env, parent=None):
        """ Class constructor.

        Args:
            env: SimPy environment.
            parent: Optional parent of this widget.
        """
        super(Window, self).__init__()
        self.env = env
        self.init()

    def init(self) -> None:
        """ Initialise the layout of the widget. Just a label that displays the
        SimPy Environment time.
        """
        layout = QtWidgets.QVBoxLayout()
        self.label = QtWidgets.QLabel('SimPy Time: {}'.format(self.env.now))
        layout.addWidget(self.label)
        self.setLayout(layout)
        self.show()

    def update(self) -> None:
        """ Update method for the window; retrieve the current SimPy environment time
        and update the label.
        """
        self.label.setText("SimPy Time: {}".format(self.env.now))

def simpy_generator(env, window):
    """ Generator for SimPy simulation; just tick the environment's clock and update
    the QtWidget's fields.

    Args:
        env: SimPy environment.
        window: QtWidget to update with SimPy data.
    """
    while True:
        window.update()
        yield env.timeout(1)

if __name__ == "__main__":

    env = simpy.Environment()
    app = QtWidgets.QApplication(sys.argv)
    window = Window(env=env)

    ### These need to be incorporated into the Qt event queue somehow?
    # simpy_process = env.process(simpy_generator(env, window))
    # env.run(until=25)

    app.exec_()

但是,我对如何使它发挥作用感到非常困惑。我知道 Qt 需要管理它的事件队列,并且更新通常会使用一些 QTimer 来完成,它会发出一个信号来触发它链接到的某个插槽的运行(Windowupdate 方法在这个案子)。但这似乎与 SimPy 自己的事件队列不兼容(或者更确切地说,我太无知了,无法理解它们应该如何交互);生成器需要作为一个进程添加到环境中,然后环境设置为运行直到完成(参见代码的注释部分)。

谁能告诉我如何才能做到这一点?

【问题讨论】:

  • 你需要在各自的线程中运行每一个,并使用线程队列在线程之间传递数据
  • 你还需要使用RealtimeEnvironment
  • @user21943 如果您的解决方案解决了问题,请不要编辑帖子,而是添加您自己的答案。如果其他人找到其他解决方案,他们将自行发布另一个答案。

标签: python asynchronous pyqt simpy event-simulation


【解决方案1】:

根据 Michael 的回答,SimPy 模拟是在独立线程上启动的。上面的代码被修改为包含以下内容:

def simpy_thread(env, window):
    """ Function to be run on a dedicated thread where the SimPy simulation will live.

    Args:
        env: SimPy environment.
        window: QtWidget to update with SimPy data.
    """
    simpy_process = env.process(simpy_generator(env, window))
    env.run(until=25)

if __name__ == "__main__":

    env = simpy.rt.RealtimeEnvironment(factor=1)

    # Create the Qt window
    app = QtWidgets.QApplication(sys.argv)
    window = Window(env=env)

    # Launch a dedicated SimPy thread that has a reference to the window for updating
    thread = threading.Thread(target=simpy_thread, args=(env,window,))
    thread.start()

    # Finally, start the Qt event queue; the code will block at this point until the window
    # object is destroyed
    app.exec_()

仍然很想知道人们是否有替代解决方案:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 2013-04-17
    • 2017-08-24
    • 2015-10-03
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多