小能豆

如何从另一个框架控制一个框架?

py

我正在编写一个具有两个独立框架的小应用程序。

第一帧就像一个视频播放器控制器。它有播放/停止/暂停按钮等。它被命名为 controller.py。

第二帧包含 OpenGL 渲染和其中的许多内容,但所有内容都包装在 Frame() 类中,如上所示。它名为 model.py。

我已经到了最后一部分,我必须将这两个“连接”在一起。有人知道如何从另一个框架 (controller.py) 控制一个框架 (model.py) 吗?

我想做一些类似电影播放器的事情,当你点击播放时它会弹出一个新窗口并播放,直到点击停止按钮。

如果你知道怎么做,请告诉我。(只要告诉我大概的意思就行,不需要具体说明)。


阅读 16

收藏
2025-01-04

共1个答案

小能豆

你的问题可以通过模块化设计和事件驱动架构来解决。这种设计允许 controller.pymodel.py 保持独立,但通过共享的接口和事件来通信。

以下是实现此目标的步骤和大致思路:


1. 设计控制器 (Controller)

controller.py 是主控制器框架,负责管理播放、暂停、停止按钮的状态,并发送事件或信号给渲染窗口(Model)。

  • 创建一个 GUI 框架(如 Tkinter、PyQt 或其他工具)。
  • 为按钮绑定事件处理函数(如 on_play_clickon_stop_click)。
  • 在事件处理函数中,调用渲染窗口的方法或发送信号。

2. 设计渲染窗口 (Model)

model.py 是独立的 OpenGL 渲染框架,封装在一个类中(如 RenderWindow),具有以下方法:

  • start_rendering():启动 OpenGL 渲染循环。
  • stop_rendering():终止渲染并关闭窗口。
  • pause_rendering():暂停渲染循环。
  • 使用线程或进程,确保渲染窗口与主控制器分离。

3. 连接两个框架

你可以通过以下方式连接两者:

方法 1:直接方法调用

  • RenderWindow 实例传递给 Controller 类。
  • 在控制器事件处理函数中调用渲染窗口的方法。

示例:

# controller.py
from model import RenderWindow

class Controller:
    def __init__(self):
        self.render_window = RenderWindow()

    def on_play_click(self):
        self.render_window.start_rendering()

    def on_stop_click(self):
        self.render_window.stop_rendering()

方法 2:使用事件机制

  • 使用 Python 的内置 queue.Queue 或信号库(如 PyQt 的信号和槽)传递事件。
  • Controller 将事件放入队列,RenderWindow 轮询队列以执行操作。

示例:

# controller.py
import queue
from model import RenderWindow

class Controller:
    def __init__(self):
        self.event_queue = queue.Queue()
        self.render_window = RenderWindow(self.event_queue)

    def on_play_click(self):
        self.event_queue.put("play")

    def on_stop_click(self):
        self.event_queue.put("stop")
# model.py
import threading
import time

class RenderWindow:
    def __init__(self, event_queue):
        self.event_queue = event_queue
        self.running = False

    def start_rendering(self):
        self.running = True
        threading.Thread(target=self.render_loop).start()

    def stop_rendering(self):
        self.running = False

    def render_loop(self):
        while self.running:
            # Check for events
            while not self.event_queue.empty():
                event = self.event_queue.get()
                if event == "stop":
                    self.running = False
                elif event == "play":
                    print("Playing...")
            # Perform OpenGL rendering
            time.sleep(0.016)  # Simulating frame rendering

4. 主程序入口

编写一个主程序,将两者结合起来。

示例:

# main.py
from controller import Controller

if __name__ == "__main__":
    controller = Controller()
    controller.run()

关键注意事项

  • 线程或进程管理:渲染窗口和控制器需要分离线程或进程运行,以避免阻塞主线程。
  • 事件循环:确保事件队列能够实时响应用户交互。
  • 窗口关闭事件:处理好窗口关闭时的资源释放和线程终止。

这样,你可以实现一个模块化的应用,controller.py 负责用户交互,model.py 专注于渲染工作。

2025-01-04