Pygame 嵌入 PyQt 时不返回事件
Pygame not returning events while embedded in PyQt
我正在测试一个应用程序,UI 使用嵌入了 Pygame 的 PyQt4。它使用一个计时器 "update" 本身可以这么说,并且在 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_()
当 Pygame window 嵌入到 PyQt 应用程序中时,如何获取 Pygame 事件?
你不能。
TL;博士;
您不能也不应该组合 2 个具有自己的事件循环的库,例如现在 Qt 事件循环阻塞了 pygame 事件循环。
首先不要混用框架。这些框架可能相互作用不佳或彼此完全冲突。
让它在您的系统上运行并不意味着它可以在另一个系统上运行或与任何框架的不同版本一起运行。
混合框架总是意味着某种未定义的行为。
在您的示例中,您使用 Pygame 库创建图像 (pygame.Surface) 并将其显示在 QWidget
中。
您永远不会创建 Pygame window。因此 Pygame 事件处理无法工作。您需要使用 Qts 事件处理。
无论如何,如果你只是想做一些图像处理或者画一些图片并在 Qt 应用程序中显示它们,我建议使用 OpenCV (cv2)。这个库是为强大的图像处理而设计的,可以使用 Qt 用户界面很好地查看图像。
我正在测试一个应用程序,UI 使用嵌入了 Pygame 的 PyQt4。它使用一个计时器 "update" 本身可以这么说,并且在 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_()
当 Pygame window 嵌入到 PyQt 应用程序中时,如何获取 Pygame 事件?
你不能。
TL;博士;
您不能也不应该组合 2 个具有自己的事件循环的库,例如现在 Qt 事件循环阻塞了 pygame 事件循环。
首先不要混用框架。这些框架可能相互作用不佳或彼此完全冲突。 让它在您的系统上运行并不意味着它可以在另一个系统上运行或与任何框架的不同版本一起运行。 混合框架总是意味着某种未定义的行为。
在您的示例中,您使用 Pygame 库创建图像 (pygame.Surface) 并将其显示在 QWidget
中。
您永远不会创建 Pygame window。因此 Pygame 事件处理无法工作。您需要使用 Qts 事件处理。
无论如何,如果你只是想做一些图像处理或者画一些图片并在 Qt 应用程序中显示它们,我建议使用 OpenCV (cv2)。这个库是为强大的图像处理而设计的,可以使用 Qt 用户界面很好地查看图像。