嵌入 PyQt 时 Pygame 不返回事件

Posted

技术标签:

【中文标题】嵌入 PyQt 时 Pygame 不返回事件【英文标题】:Pygame not returning events while embedded in PyQt 【发布时间】:2020-01-13 20:27:22 【问题描述】:

我正在测试一个应用程序,用户界面使用 PyQt4,其中嵌入了 Pygame。可以这么说,它使用计时器来“更新”自身,并且在 timerEvent 函数中 Pygame 尝试检索所有检测到的事件。问题是,Pygame 没有检测到任何事件。

这是我的代码的极简版本

#!/etc/python2.7
from PyQt4 import QtGui
from PyQt4 import QtCore
import pygame
import sys

class ImageWidget(QtGui.QWidget):
    def __init__(self,surface,parent=None):
        super(ImageWidget,self).__init__(parent)
        w=surface.get_width()
        h=surface.get_height()
        self.data=surface.get_buffer().raw
        self.image=QtGui.QImage(self.data,w,h,QtGui.QImage.Format_RGB32)

        self.surface = surface

        self.timer = QtCore.QBasicTimer()
        self.timer.start(500, self)

    def timerEvent(self, event):
        w=self.surface.get_width()
        h=self.surface.get_height()
        self.data=self.surface.get_buffer().raw
        self.image=QtGui.QImage(self.data,w,h,QtGui.QImage.Format_RGB32)
        self.update()

        for ev in pygame.event.get():
            if ev.type == pygame.MOUSEBUTTONDOWN:
                print "Mouse down"

    def paintEvent(self,event):
        qp=QtGui.QPainter()
        qp.begin(self)
        qp.drawImage(0,0,self.image)
        qp.end()


class MainWindow(QtGui.QMainWindow):
    def __init__(self,surface,parent=None):
        super(MainWindow,self).__init__(parent)
        self.setCentralWidget(ImageWidget(surface))



pygame.init()
s=pygame.Surface((640,480))
s.fill((64,128,192,224))
pygame.draw.circle(s,(255,255,255,255),(100,100),50)

app=QtGui.QApplication(sys.argv)
w=MainWindow(s)
w.show()
app.exec_()

如何在 PyQt 应用程序中嵌入 Pygame 窗口时获取 Pygame 事件?

【问题讨论】:

你不能也不应该合并 2 个有自己的事件循环的库,例如现在 Qt 事件循环阻塞了 pygame 事件循环。 那么在这种情况下是不可能获取Pygame事件的? 是的,不可能。 现在我很难过 如果Qt涵盖了pygame的所有功能,我不明白使用pygame的必要性 【参考方案1】:

首先不要混合框架。这些框架可能相互作用不佳或完全相互冲突。 让它在您的系统上运行并不意味着它可以在另一个系统上运行或与任何框架的不同版本一起运行。 混合框架总是意味着某种未定义的行为。

在您的示例中,您使用 Pygame 库创建图像 (pygame.Surface) 并将其显示在 QWidget 中。 你永远不会创建一个 Pygame 窗口。因此 Pygame 事件处理无法工作。您需要使用 Qts 事件处理。

无论如何,如果你只是想做一些图像处理或绘制一些图片并在 Qt 应用程序中显示它们,我建议使用OpenCV (cv2)。该库专为强大的图像处理而设计,可以使用 Qt 用户界面很好地查看图像。

【讨论】:

这是一个较老的问题,但我很感激您花时间写出这个解决方案。谢谢【参考方案2】:

你不能。


TL;博士;

你不能也不应该合并两个有自己的事件循环的库,例如现在 Qt 事件循环阻塞了 pygame 事件循环。

【讨论】:

@Rabbid76 您回答的第一部分与我所指出的相同,在其他部分中您仅指出可能的解决方案。在 pygame 窗口的情况下,可以在 Qt 中使用它,但这是不必要的努力,因为 Qt 可以做与 pygame 相同的事情。出于这个原因,我指出它不好,虽然可能最好只使用 Qt 或只使用 pygame。

以上是关于嵌入 PyQt 时 Pygame 不返回事件的主要内容,如果未能解决你的问题,请参考以下文章

Pygame blit图像与鼠标事件

PyQt5-Qt Designer鼠标+键盘事件

为啥 Python 会在 Pygame 中为“事件”变量抛出未绑定的本地错误? [关闭]

是否必须以不同的方式处理键盘事件才能在 Matplotlib/PyQt5 中选择事件? [复制]

Webview 不响应触摸事件

将 MIDI 事件转换为 pygame 事件