我正在try 用python制作一个应用程序,其中的可见窗口是pyglet窗口.问题是,我同时需要图形功能和与HTML页面的交互.我将使用PyQt6与HTML进行通信.所以问题是,如何让PyQT6窗口在Pyglet窗口内渲染?

我的当前代码:

import pyglet
from pyglet.gl import *
import sys
from PyQt6.QtWidgets import QApplication, QWidget

app = QApplication(sys.argv)

w = QWidget()
w.resize(250, 200)
w.move(300, 300)

w.setWindowTitle('Simple')
w.show()

window = pyglet.window.Window(800, 600, "Radium")

@window.event
def on_draw():
    window.clear()
    # Render window with OpenGL
    # ...

pyglet.app.run()

sys.exit(app.exec())

推荐答案

我不确定是否可以在Pyglet窗口中渲染PyQT.它有自己的渲染和绘图系统,无法在将其集成到pyglet窗口所需的较低级别上访问.

但是,您可以在QT中使用OpenGL(并通过扩展使用pyglet)进行反向操作.然而,这也意味着您需要在这两方面都有经验,才能真正使其工作良好.

我使用PyQt6制作了一个可运行的示例:

import sys
import pyglet
#from PyQt5 import QtGui
#from PyQt5 import QtCore, QtWidgets
#from PyQt5.QtOpenGL import QGLWidget as OpenGLWidget
from PyQt6 import QtGui
from PyQt6 import QtCore, QtWidgets
from PyQt6.QtOpenGLWidgets import QOpenGLWidget as OpenGLWidget
from pyglet.gl import glClear, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT
import random


"""An example showing how to use pyglet in QT, utilizing the OGLWidget.

   Since this relies on the QT Window, any events called on Pyglet Window
   will NOT be called.
    
   This includes mouse, keyboard, tablet, and anything else relating to the Window
   itself. These must be handled by QT itself.
   
   This just allows user to create and use pyglet related things such as sprites, shapes,
   batches, clock scheduling, sound, etc.           
"""

class MainWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__()
        self.setWindowTitle("Pyglet and QT Example")
        self.shapes = []

        width, height = 640, 480
        self.opengl = PygletWidget(width, height)
        self.sprite_button = QtWidgets.QPushButton('Create Rectangle', self)
        self.sprite_button.clicked.connect(self.create_sprite_click)

        self.clear_sprite_button = QtWidgets.QPushButton('Clear Shapes', self)
        self.clear_sprite_button.clicked.connect(self.clear_sprite_click)
        
        mainLayout = QtWidgets.QVBoxLayout()
        mainLayout.addWidget(self.opengl)
        mainLayout.addWidget(self.sprite_button)
        mainLayout.addWidget(self.clear_sprite_button)
        self.setLayout(mainLayout)

    def create_sprite_click(self):
        gl_width, gl_height = self.opengl.size().width(), self.opengl.size().height()
        
        width = random.randint(50, 100)
        height = random.randint(50, 100)
        
        x = random.randint(0, gl_width-width)
        y = random.randint(0, gl_height-height)
        color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        
        shape = pyglet.shapes.Rectangle(x, y, width, height, color=color, batch=self.opengl.batch)
        shape.opacity = random.randint(100, 255)
        self.shapes.append(shape)
        
    def clear_sprite_click(self):
        for shape in self.shapes:
            shape.delete()
            
        self.shapes.clear()


class PygletWidget(OpenGLWidget):
    def __init__(self, width, height, parent=None):
        super().__init__(parent)
        self.setMinimumSize(width, height)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self._pyglet_update)
        self.timer.setInterval(0)
        self.timer.start()

    def _pyglet_update(self):
        # Tick the pyglet clock, so scheduled events can work.
        pyglet.clock.tick()  
        
        # Force widget to update, otherwise paintGL will not be called.
        self.update()  # self.updateGL() for pyqt5

    def paintGL(self):
        """Pyglet equivalent of on_draw event for window"""
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        
        self.batch.draw()

    def initializeGL(self):
        """Call anything that needs a context to be created."""
        self.batch = pyglet.graphics.Batch()
        size = self.size()
        w, h = size.width(), size.height()
        
        self.projection = pyglet.window.Projection2D()
        self.projection.set(w, h, w, h)


if __name__ == '__main__':    
    app = QtWidgets.QApplication(sys.argv)    
    window = QtWidgets.QMainWindow()
    ui = MainWidget(window)    
    ui.show()  # Calls initializeGL. Do not do any GL stuff before this is called.
    app.exec() # exec_ in 5.

Python相关问答推荐

如何判断LazyFrame是否为空?

Polars Select 多个元素产品

机器人与Pyton Minecraft服务器状态不和

如何将带有逗号分隔的数字的字符串解析为int Array?

Pystata:从Python并行运行stata实例

韦尔福德方差与Numpy方差不同

在Google Colab中设置Llama-2出现问题-加载判断点碎片时Cell-run失败

如何将Docker内部运行的mariadb与主机上Docker外部运行的Python脚本连接起来

我们可以为Flask模型中的id字段主键设置默认uuid吗

对所有子图应用相同的轴格式

Python—从np.array中 Select 复杂的列子集

如何在表中添加重复的列?

在Django admin中自动完成相关字段筛选

计算天数

Django—cte给出:QuerySet对象没有属性with_cte''''

解决调用嵌入式函数的XSLT中表达式的语法移位/归约冲突

如何在达到end_time时自动将状态字段从1更改为0

如何在BeautifulSoup/CSS Select 器中处理regex?

numpy.unique如何消除重复列?

如何在一组行中找到循环?